diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 3157d16a..2ccc3964 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1,6 +1,7 @@ on: pull_request: branches: + - feat/stable-cadence - main name: pr diff --git a/auction_test.go b/auction_test.go deleted file mode 100644 index db77d1ad..00000000 --- a/auction_test.go +++ /dev/null @@ -1,434 +0,0 @@ -package test_main - -import ( - "testing" - - . "github.com/bjartek/overflow/v2" - "github.com/stretchr/testify/assert" -) - -/* -Tests must be in the same folder as flow.json with contracts and transactions/scripts in subdirectories in order for the path resolver to work correctly -this tests must be split up or rename, it could be called TestFindNativeMarket -*/ -func TestAuction(t *testing.T) { - otu := &OverflowTestUtils{T: t, O: ot.O} - - findSaleEvent, err := otu.O.QualifiedIdentifier("FIND", "Sale") - assert.NoError(t, err) - - ftDeposit, err := otu.O.QualifiedIdentifier("FungibleToken", "Deposited") - assert.NoError(t, err) - - // TODO: Why is this test in auction test? - ot.Run(t, "Should list a name for sale", func(t *testing.T) { - otu.listForSale("user1") - }) - - ot.Run(t, "Should be able list names for sale and delist some", func(t *testing.T) { - otu.registerUserWithName("user1", "name1"). - registerUserWithName("user1", "name2"). - listForSale("user1"). - listNameForSale("user1", "user1"). - listNameForSale("user1", "name1"). - setProfile("user1") - - otu.O.Tx("delistNameSale", - WithSigner("user1"), - WithArg("names", `["user1","name1"]`), - ). - AssertSuccess(t). - AssertEvent(t, findSaleEvent, map[string]interface{}{ - "amount": 10.0, - "name": "name1", - "seller": otu.O.Address("user1"), - "sellerName": "user1", - "status": "cancel", - }). - AssertEvent(t, findSaleEvent, map[string]interface{}{ - "amount": 10.0, - "name": "user1", - "seller": otu.O.Address("user1"), - "sellerName": "user1", - "status": "cancel", - }) - }) - - ot.Run(t, "Should be able to direct offer on name for sale", func(t *testing.T) { - otu.listForSale("user1") - otu.directOffer("user2", "user1", 4.0) - }) - - ot.Run(t, "Should be able to direct offer on name for sale and fulfill it", func(t *testing.T) { - otu.listForSale("user1"). - directOffer("user2", "user1", 4.0) - - otu.O.Tx("fulfillName", - WithSigner("user1"), - WithArg("name", "user1"), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.DirectOffer", map[string]interface{}{ - "name": "user1", - "buyerName": "user2", - "status": "sold", - }). - AssertEvent(t, ftDeposit, map[string]interface{}{ - "amount": 3.8, - "to": otu.O.Address("user1"), - }). - AssertEvent(t, ftDeposit, map[string]interface{}{ - "amount": 0.2, - "to": otu.O.Address("find-admin"), - }) - }) - - ot.Run(t, "Should be able to sell lease from auction buyer can fulfill auction", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 20.0). - expireAuction() - - otu.O.Tx("fulfillNameAuction", - WithSigner("user3"), - WithArg("owner", "user1"), - WithArg("name", "user1"), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.EnglishAuction", map[string]interface{}{ - "name": "user1", - "seller": otu.O.Address("user1"), - "amount": 20.0, - "status": "sold", - "buyer": otu.O.Address("user2"), - "buyerAvatar": "https://find.xyz/assets/img/avatars/avatar14.png", - "buyerName": "user2", - }). - AssertEvent(t, ftDeposit, map[string]interface{}{ - "amount": 19.0, - "to": otu.O.Address("user1"), - }). - AssertEvent(t, ftDeposit, map[string]interface{}{ - "amount": 1.0, - "to": otu.O.Address("find-admin"), - }) - }) - - ot.Run(t, "Should not allow auction bid lower then the current one", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 8.0) - - otu.O.Tx("bidName", - WithSigner("user3"), - WithArg("name", "user1"), - WithArg("amount", 5.0), - ). - AssertFailure(t, "bid must be larger then current bid. Current bid is : 8.00000000. New bid is at : 5.00000000") - }) - - ot.Run(t, "Should not start auction if bid lower then sale price", func(t *testing.T) { - otu.listForAuction("user1"). - directOffer("user2", "user1", 4.0) - }) - - ot.Run(t, "Should not accept direct offer bid less then current one", func(t *testing.T) { - otu.directOffer("user2", "user1", 10.0) - - otu.O.Tx("bidName", - WithSigner("user3"), - WithArg("name", "user1"), - WithArg("amount", 5.0), - ). - AssertFailure(t, "There is already a higher bid on this lease. Current bid is : 10.00000000 New bid is at : 5.00000000") - }) - - ot.Run(t, "Should not be able to increase direct offer price less than increment", func(t *testing.T) { - otu.directOffer("user2", "user1", 10.0) - - otu.O.Tx("increaseNameBid", - WithSigner("user2"), - WithArg("name", "user1"), - WithArg("amount", 5.0), - ). - AssertFailure(t, "Increment should be greater than 10.00000000") - }) - - ot.Run(t, "Should start auction if we start out with smaller bid and then increase it with locked user", func(t *testing.T) { - otu.expireLease(). - listForAuction("user1"). - directOffer("user2", "user1", 4.0) - - otu.O.Tx("increaseNameBid", - WithSigner("user2"), - WithArg("name", "user1"), - WithArg("amount", 10.0), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.EnglishAuction", map[string]interface{}{ - "name": "user1", - "seller": otu.O.Address("user1"), - "amount": 14.0, - "status": "active_ongoing", - "buyerName": "user2", - }) - }) - ot.Run(t, "Should not allow double bid from same author", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 10.0) - - otu.O.Tx("bidName", - WithSigner("user2"), - WithArg("name", "user1"), - WithArg("amount", 15.0), - ). - AssertFailure(t, "You already have the latest bid on this item, use the incraseBid transaction") - }) - - ot.Run(t, "Should start auction if we start out with smaller bid and then increase it", func(t *testing.T) { - otu.listForAuction("user1"). - directOffer("user2", "user1", 4.0) - - otu.O.Tx("increaseNameBid", - WithSigner("user2"), - WithArg("name", "user1"), - WithArg("amount", 10.0), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.EnglishAuction", map[string]interface{}{ - "name": "user1", - "seller": otu.O.Address("user1"), - "amount": 14.0, - "status": "active_ongoing", - "buyerName": "user2", - }) - }) - - ot.Run(t, "Should be able to manually start auction with lower bid", func(t *testing.T) { - otu.listForAuction("user1"). - directOffer("user2", "user1", 4.0) - - otu.O.Tx("startNameAuction", - WithSigner("user1"), - WithArg("name", "user1"), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.EnglishAuction", map[string]interface{}{ - "name": "user1", - "seller": otu.O.Address("user1"), - "amount": 4.0, - "status": "active_ongoing", - "buyerName": "user2", - }) - }) - ot.Run(t, "Should be able to cancel blind bid", func(t *testing.T) { - otu.listForSale("user1"). - directOffer("user2", "user1", 4.0) - - otu.O.Tx("cancelNameBid", - WithSigner("user2"), - WithArg("names", `["user1"]`), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.DirectOffer", map[string]interface{}{ - "name": "user1", - "seller": otu.O.Address("user1"), - "sellerName": "user1", - "amount": 4.0, - "status": "cancel_rejected", - "buyerName": "user2", - }) - }) - ot.Run(t, "Should be able to cancel blind bid when user locked", func(t *testing.T) { - otu.listForSale("user1"). - directOffer("user2", "user1", 4.0). - expireLease() - - otu.O.Tx("cancelNameBid", - WithSigner("user2"), - WithArg("names", `["user1"]`), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.DirectOffer", map[string]interface{}{ - "name": "user1", - "seller": otu.O.Address("user1"), - "sellerName": "user1", - "amount": 4.0, - "status": "cancel_rejected", - "buyerName": "user2", - }) - }) - - ot.Run(t, "Should not be able to cancel bid when auction has started", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 5.0) - - otu.O.Tx("cancelNameBid", - WithSigner("user2"), - WithArg("names", `["user1"]`), - ). - AssertFailure(t, "Cannot cancel a bid that is in an auction") - }) - - ot.Run(t, "Should return money if outbid", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 5.0) - - otu.O.Tx("bidName", - WithSigner("user3"), - WithArg("name", "user1"), - WithArg("amount", 15.0), - ). - AssertSuccess(t). - AssertEvent(t, ftDeposit, map[string]interface{}{ - "amount": 5.0, - "to": otu.O.Address("user2"), - }) - }) - ot.Run(t, "Should extend auction on late bid", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 5.0) - - otu.tickClock(86380.0) - - otu.O.Tx("bidName", - WithSigner("user3"), - WithArg("name", "user1"), - WithArg("amount", 15.0), - ). - AssertSuccess(t). - AssertEvent(t, "FIND.EnglishAuction", map[string]interface{}{ - "name": "user1", - "endsAt": 86681.0, - }) - }) - - ot.Run(t, "Should be able to cancel unfinished auction", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 5.0) - - otu.O.Tx("cancelNameAuction", - WithSigner("user1"), - WithArg("names", `["user1"]`), - ). - AssertSuccess(t). - AssertEvent(t, ftDeposit, map[string]interface{}{ - "amount": 5.0, - "to": otu.O.Address("user2"), - }). - AssertEvent(t, "FIND.EnglishAuction", map[string]interface{}{ - "name": "user1", - "seller": otu.O.Address("user1"), - "sellerName": "user1", - "amount": 5.0, - "status": "cancel_listing", - "buyerName": "user2", - }) - }) - ot.Run(t, "Should not be able to bid on lease that is free, and not cleaned up", func(t *testing.T) { - otu.listForSale("user1") - - otu.expireLease().tickClock(2.0) - otu.expireLock().tickClock(2.0) - - otu.O.Tx("bidName", - WithSigner("user2"), - WithArg("name", "user1"), - WithArg("amount", 10.0), - ). - AssertFailure(t, "cannot bid on name that is free") - }) - - ot.Run(t, "Should be able to cancel finished auction that did not meet reserve price", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 15.0). - expireAuction().tickClock(2.0) - - otu.O.Tx("cancelNameAuction", - WithSigner("user1"), - WithArg("names", `["user1"]`), - ).AssertSuccess(t). - AssertEvent(t, "FIND.EnglishAuction", - map[string]interface{}{ - "amount": 15.0, - "auctionReservePrice": 20.0, - "buyer": otu.O.Address("user2"), - "seller": otu.O.Address("user1"), - }, - ) - }) - - ot.Run(t, "Should not be able to cancel finished auction", func(t *testing.T) { - otu.listForAuction("user1"). - bid("user2", "user1", 25.0). - expireAuction().tickClock(2.0) - - otu.O.Tx("cancelNameAuction", - WithSigner("user1"), - WithArg("names", `["user1"]`), - ). - AssertFailure(t, "Cannot cancel finished auction") - - otu.O.Tx("fulfillNameAuction", - WithSigner("user2"), - WithArg("owner", "user1"), - WithArg("name", "user1"), - ).AssertSuccess(t) - }) - - ot.Run(t, "Should not be able to direct offer on your own name", func(t *testing.T) { - otu.O.Tx("bidName", - WithSigner("user1"), - WithArg("name", "user1"), - WithArg("amount", 5.0), - ). - AssertFailure(t, "cannot bid on your own name") - }) - - ot.Run(t, "Should cancel previous bid if put for auction", func(t *testing.T) { - otu.directOffer("user2", "user1", 5.0) - - name := "user1" - - otu.O.Tx("listNameForAuction", - WithSigner(name), - WithArg("name", name), - WithArg("auctionStartPrice", 5.0), - WithArg("auctionReservePrice", 20.0), - WithArg("auctionDuration", auctionDurationFloat), - WithArg("auctionExtensionOnLateBid", 300.0), - ).AssertSuccess(t). - AssertEvent(t, "FIND.EnglishAuction", map[string]interface{}{ - "name": name, - "seller": otu.O.Address(name), - "sellerName": name, - "amount": 5.0, - "status": "active_listed", - }). - AssertEvent(t, "FIND.DirectOffer", map[string]interface{}{ - "name": name, - "seller": otu.O.Address(name), - "sellerName": name, - "amount": 5.0, - "buyer": otu.O.Address("user2"), - "buyerName": "user2", - "status": "rejected", - }) - }) - - ot.Run(t, "Should register previousBuyer if direct offer outbid", func(t *testing.T) { - otu.directOffer("user2", "user1", 4.0) - - otu.O.Tx("bidName", - WithSigner("user3"), - WithArg("name", "user1"), - WithArg("amount", 10.0), - ).AssertSuccess(t). - AssertEvent(t, "FIND.DirectOffer", - map[string]interface{}{ - "amount": 10.0, - "buyer": otu.O.Address("user3"), - "previousBuyer": otu.O.Address("user2"), - "seller": otu.O.Address("user1"), - }, - ) - }) -} diff --git a/contracts/FIND.cdc b/contracts/FIND.cdc index e5f9a39c..0afda65e 100644 --- a/contracts/FIND.cdc +++ b/contracts/FIND.cdc @@ -1,7 +1,6 @@ import "FungibleToken" import "FUSD" import "FlowToken" -// import "FiatToken" import "DapperUtilityCoin" import "Profile" import "Debug" @@ -9,14 +8,14 @@ import "Clock" import "Sender" import "ProfileCache" import "FindUtils" +import "PublicPriceOracle" /* - ///FIND ///Flow Integrated Name Directory - A naming service on flow, -/// Lease a name in the network for as little as 5 FUSD a year, (4 characters cost 100, 3 cost 500) +/// Lease a name in the network for as little as 5 USD a year, (4 characters cost 100, 3 cost 500) Taxonomy: @@ -27,22 +26,6 @@ Taxonomy: - leaseStatus: FREE|TAKEN|LOCKED, a LOCKED lease can be reopend by the owner. A lease will be locked for 90 days before it is freed */ access(all) contract FIND { - //Old events not in use anymore we cannot remove - access(all) event Sold() - access(all) event SoldAuction() - access(all) event DirectOfferRejected() - access(all) event DirectOfferCanceled() - access(all) event AuctionStarted() - access(all) event AuctionCanceled() - access(all) event AuctionBid() - access(all) event AuctionCanceledReservePrice() - access(all) event ForSale() - access(all) event ForAuction() - - // Deprecated in testnet - access(all) event TokensRewarded() - access(all) event TokensCanNotBeRewarded() - //event when FT is sent access(all) event FungibleTokenSent(from:Address, fromName:String?, name:String, toAddress:Address, message:String, tag:String, amount: UFix64, ftType:String) @@ -57,21 +40,6 @@ access(all) contract FIND { /// Emitted when a name is moved to a new owner access(all) event Moved(name: String, previousOwner: Address, newOwner: Address, validUntil: UFix64, lockedUntil: UFix64) - /// Emitted when a name is explicistly put up for sale - access(all) event Sale(name: String, uuid:UInt64, seller: Address, sellerName: String?, amount: UFix64, status: String, vaultType:String, buyer:Address?, buyerName:String?, buyerAvatar: String?, validUntil: UFix64, lockedUntil: UFix64) - - /// Emitted when an name is put up for on-demand auction - access(all) event EnglishAuction(name: String, uuid:UInt64, seller: Address, sellerName:String?, amount: UFix64, auctionReservePrice: UFix64, status: String, vaultType:String, buyer:Address?, buyerName:String?, buyerAvatar: String?, endsAt: UFix64?, validUntil: UFix64, lockedUntil: UFix64, previousBuyer:Address?, previousBuyerName:String?) - - /// Emitted if a bid occurs at a name that is too low or not for sale - access(all) event DirectOffer(name: String, uuid:UInt64, seller: Address, sellerName: String?, amount: UFix64, status: String, vaultType:String, buyer:Address?, buyerName:String?, buyerAvatar: String?, validUntil: UFix64, lockedUntil: UFix64, previousBuyer:Address?, previousBuyerName:String?) - - access(all) event RoyaltyPaid(name: String, uuid: UInt64, address: Address, findName:String?, royaltyName:String, amount: UFix64, vaultType:String, saleType: String) - - //store bids made by a bidder to somebody elses leases - access(all) let BidPublicPath: PublicPath - access(all) let BidStoragePath: StoragePath - //store the network itself access(all) let NetworkStoragePath: StoragePath @@ -86,8 +54,64 @@ access(all) contract FIND { panic("Network is not set up") } + ////////////////////////////////////////// + // ORACLE + ////////////////////////////////////////// + // Get the latest FLOW/USD price + //This uses the FLOW/USD increment.fi oracle + access(all) fun getLatestPrice(): UFix64 { + let lastResult = PublicPriceOracle.getLatestPrice(oracleAddr: self.getFlowUSDOracleAddress()) + let lastBlockNum = PublicPriceOracle.getLatestBlockHeight(oracleAddr: self.getFlowUSDOracleAddress()) + + // Make sure the price is not expired + if getCurrentBlock().height - lastBlockNum > 2000 { + panic("Price is expired") + } + + return lastResult + } + + + access(all) fun convertFLOWToUSD(_ amount: UFix64): UFix64 { + return amount * self.getLatestPrice() + } + + access(all) fun convertUSDToFLOW(_ amount: UFix64): UFix64 { + return amount / self.getLatestPrice() + } + + ////////////////////////////////////////// + // HELPER FUNCTIONS + ////////////////////////////////////////// //These methods are basically just here for convenience + // + + access(all) fun calculateCostInFlow(_ name:String) : UFix64 { + if !FIND.validateFindName(name) { + panic("A FIND name has to be lower-cased alphanumeric or dashes and between 3 and 16 characters") + } + + if let network = FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath) { + return self.convertUSDToFLOW(network.calculateCost(name)) + } + panic("Network is not set up") + } + + access(all) fun calculateAddonCostInFlow(_ addon: String) : UFix64 { + let network=FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath)! + + if !network.publicEnabled { + panic("Public registration is not enabled yet") + } + + if network.addonPrices[addon] == nil { + panic("This addon is not available. addon : ".concat(addon)) + } + var addonPrice = network.addonPrices[addon]! + let cost= FIND.convertUSDToFLOW(addonPrice) + return cost + } /// Calculate the cost of an name /// @param _ the name to calculate the cost for @@ -231,8 +255,8 @@ access(all) contract FIND { var path = "" if vault.getType() == Type<@FlowToken.Vault>() { path ="flowTokenReceiver" - } else if vault.getType() == Type<@FUSD.Vault>() { - path="fusdReceiver" + } else { + panic("Could not find a valid receiver for this vault type") } if path != "" { emit FungibleTokenSent(from: fromAddress, fromName: FIND.reverseLookup(fromAddress), name: "", toAddress: address, message:message, tag:tag, amount:vault.balance, ftType:vault.getType().identifier) @@ -304,6 +328,9 @@ access(all) contract FIND { access(all) resource Lease { access(contract) let name: String access(contract) let networkCap: Capability<&Network> + access(contract) var addons: {String: Bool} + + //These fields are here, but they are not in use anymore access(contract) var salePrice: UFix64? access(contract) var auctionStartPrice: UFix64? access(contract) var auctionReservePrice: UFix64? @@ -311,7 +338,6 @@ access(all) contract FIND { access(contract) var auctionMinBidIncrement: UFix64 access(contract) var auctionExtensionOnLateBid: UFix64 access(contract) var offerCallback: Capability<&BidCollection>? - access(contract) var addons: {String: Bool} init(name:String, networkCap: Capability<&Network>) { self.name=name @@ -345,35 +371,7 @@ access(all) contract FIND { self.addons[addon]=true } - access(LeaseOwner) fun setExtentionOnLateBid(_ time: UFix64) { - self.auctionExtensionOnLateBid=time - } - - access(LeaseOwner) fun setAuctionDuration(_ duration: UFix64) { - self.auctionDuration=duration - } - - access(LeaseOwner) fun setSalePrice(_ price: UFix64?) { - self.salePrice=price - } - - access(LeaseOwner) fun setReservePrice(_ price: UFix64?) { - self.auctionReservePrice=price - } - - access(LeaseOwner) fun setMinBidIncrement(_ price: UFix64) { - self.auctionMinBidIncrement=price - } - - access(LeaseOwner) fun setStartAuctionPrice(_ price: UFix64?) { - self.auctionStartPrice=price - } - - access(LeaseOwner) fun setCallback(_ callback: Capability<&BidCollection>?) { - self.offerCallback=callback - } - - access(LeaseOwner) fun extendLease(_ vault: @FUSD.Vault) { + access(LeaseOwner) fun extendLease(_ vault: @FlowToken.Vault) { let network= self.networkCap.borrow() ?? panic("The network is not up") network.renew(name: self.name, vault:<- vault) } @@ -467,73 +465,7 @@ access(all) contract FIND { } } - access(all) entitlement AuctionOwner - - /* An Auction for a lease */ - access(all) resource Auction { - access(contract) var endsAt: UFix64 - access(contract) var startedAt: UFix64 - access(contract) let extendOnLateBid: UFix64 - access(contract) var latestBidCallback: Capability<&BidCollection> - access(contract) let name: String - - init(endsAt: UFix64, startedAt: UFix64, extendOnLateBid: UFix64, latestBidCallback: Capability<&BidCollection>, name: String) { - - if startedAt >= endsAt { - panic("Cannot start before it will end") - } - if extendOnLateBid == 0.0 { - panic("Extends on late bid must be a non zero value") - } - self.endsAt=endsAt - self.startedAt=startedAt - self.extendOnLateBid=extendOnLateBid - self.latestBidCallback=latestBidCallback - self.name=name - } - - access(all) fun getBalance() : UFix64 { - let cb = self.latestBidCallback.borrow() ?? panic("The bidder has unlinked the capability. bidder address: ".concat(self.latestBidCallback.address.toString())) - return cb.getBalance(self.name) - } - - access(account) fun addBid(callback: Capability<&BidCollection>, timestamp: UFix64, lease: &Lease) { - let offer=callback.borrow()! - offer.setBidType(name: self.name, type: "auction") - - var previousBuyer: Address?=nil - if callback.address != self.latestBidCallback.address { - if offer.getBalance(self.name) <= self.getBalance() { - panic("bid must be larger then current bid. Current bid is : ".concat(self.getBalance().toString()).concat(". New bid is at : ").concat(offer.getBalance(self.name).toString())) - } - previousBuyer=self.latestBidCallback.address - //we send the money back - self.latestBidCallback.borrow()!.cancel(self.name) - } - self.latestBidCallback=callback - let suggestedEndTime=timestamp+self.extendOnLateBid - if suggestedEndTime > self.endsAt { - self.endsAt=suggestedEndTime - } - - let bidder= callback.address - let profile=getAccount(bidder).capabilities.borrow<&{Profile.Public}>(Profile.publicPath) - if profile == nil { - panic("Create a profile before you make a bid") - } - let bidderName= profile!.getName() - let bidderAvatar= profile!.getAvatar() - let owner=lease.owner!.address - let ownerName=self.name - var previousBuyerName:String?=nil - if let pb = previousBuyer { - previousBuyerName=FIND.reverseLookup(pb) - } - - emit EnglishAuction(name: self.name, uuid: lease.uuid, seller: owner, sellerName:ownerName, amount: offer.getBalance(self.name), auctionReservePrice: lease.auctionReservePrice!, status: "active_ongoing", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar:bidderAvatar, endsAt: self.endsAt ,validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:previousBuyer, previousBuyerName:previousBuyerName) - } - } //struct to expose information about leases access(all) struct LeaseInformation { @@ -598,15 +530,7 @@ access(all) contract FIND { //add a new lease token to the collection, can only be called in this contract access(contract) fun deposit(token: @FIND.Lease) - access(contract)fun cancelUserBid(_ name: String) - access(contract) fun increaseBid(_ name: String, balance: UFix64) - - //place a bid on a token - access(contract) fun registerBid(name: String, callback: Capability<&BidCollection>) - - //anybody should be able to fulfill an auction as long as it is done - access(all) fun fulfillAuction(_ name: String) - access(all) fun buyAddon(name:String, addon: String, vault: @FUSD.Vault) + access(all) fun buyAddon(name:String, addon: String, vault: @FlowToken.Vault) access(all) fun buyAddonDapper(merchAccount: Address, name:String, addon:String, vault: @DapperUtilityCoin.Vault) access(account) fun adminAddAddon(name:String, addon: String) access(all) fun getAddon(name:String) : [String] @@ -636,21 +560,11 @@ access(all) contract FIND { self.networkWallet=networkWallet } - access(all) fun buyAddon(name:String, addon:String, vault: @FUSD.Vault) { + access(all) fun buyAddon(name:String, addon:String, vault: @FlowToken.Vault) { if !self.leases.containsKey(name) { panic("Invalid name=".concat(name)) } - - let network=FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath)! - - if !network.publicEnabled { - panic("Public registration is not enabled yet") - } - - if network.addonPrices[addon] == nil { - panic("This addon is not available. addon : ".concat(addon)) - } - let addonPrice = network.addonPrices[addon]! + let cost=FIND.calculateAddonCostInFlow(addon) let lease = self.borrowAuth(name) @@ -662,8 +576,8 @@ access(all) contract FIND { panic("You already have this addon : ".concat(addon)) } - if vault.balance != addonPrice { - panic("Expect ".concat(addonPrice.toString()).concat(" FUSD for ").concat(addon).concat(" addon")) + if vault.balance != cost { + panic("Expect ".concat(cost.toString()).concat(" FLOW for ").concat(addon).concat(" addon")) } lease.addAddon(addon) @@ -785,18 +699,6 @@ access(all) contract FIND { var auctionEnds: UFix64?= nil var latestBidBy: Address?=nil - if self.auctions.containsKey(name) { - let auction = self.borrowAuction(name) - auctionEnds= auction.endsAt - latestBid= auction.getBalance() - latestBidBy= auction.latestBidCallback.address - } else { - if let callback = token.offerCallback { - latestBid= callback.borrow()!.getBalance(name) - latestBidBy=callback.address - } - } - return LeaseInformation(name: name, status: token.getLeaseStatus(), validUntil: token.getLeaseExpireTime(), lockedUntil: token.getLeaseLockedUntil(), latestBid: latestBid, auctionEnds: auctionEnds, salePrice: token.salePrice, latestBidBy: latestBidBy, auctionStartPrice: token.auctionStartPrice, auctionReservePrice: token.auctionReservePrice, extensionOnLateBid: token.auctionExtensionOnLateBid, address: token.owner!.address, addons: token.getAddon()) } @@ -822,621 +724,151 @@ access(all) contract FIND { return info } - //call this to start an auction for this lease - access(LeaseOwner) fun startAuction(_ name: String) { - let timestamp=Clock.time() - let lease = self.borrowAuth(name) + access(LeaseOwner) fun move(name: String, profile: Capability<&{Profile.Public}>, to: Capability<&LeaseCollection>) { + + let lease = self.borrowAuth(name) if !lease.validate() { panic("This is not a valid lease. Lease already expires and some other user registered it. Lease : ".concat(name)) } - let duration=lease.auctionDuration - let extensionOnLateBid=lease.auctionExtensionOnLateBid - if lease.offerCallback == nil { - panic("cannot start an auction on a name without a bid, set salePrice") - } + let token <- self.leases.remove(key: name) ?? panic("missing NFT") + emit Moved(name: name, previousOwner:self.owner!.address, newOwner: profile.address, validUntil: token.getLeaseExpireTime(), lockedUntil: token.getLeaseLockedUntil()) + token.move(profile: profile) + let walletRef = to.borrow() ?? panic("The receiver capability is not valid. wallet address : ".concat(to.address.toString())) + walletRef.deposit(token: <- token) - let callback=lease.offerCallback! - let offer=callback.borrow()! - offer.setBidType(name: name, type: "auction") + } - let bidder= callback.address - let bidderProfile= getAccount(bidder).capabilities.borrow<&{Profile.Public}>(Profile.publicPath) ?? panic("Bidder unlinked the profile capability. bidder address : ".concat(bidder.toString())) - let bidderName= bidderProfile.getName() - let bidderAvatar= bidderProfile.getAvatar() - let owner=lease.owner!.address - let ownerName=lease.name + //depoit a lease token into the lease collection, not available from the outside + access(contract) fun deposit(token: @FIND.Lease) { + // add the new token to the dictionary which removes the old one + let oldToken <- self.leases[token.name] <- token - let endsAt=timestamp + duration - emit EnglishAuction(name: name, uuid:lease.uuid, seller: owner, sellerName:FIND.reverseLookup(owner), amount: offer.getBalance(name), auctionReservePrice: lease.auctionReservePrice!, status: "active_ongoing", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar:bidderAvatar, endsAt: endsAt, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) + destroy oldToken + } - let oldAuction <- self.auctions[name] <- create Auction(endsAt:endsAt, startedAt: timestamp, extendOnLateBid: extensionOnLateBid, latestBidCallback: callback, name: name) - lease.setCallback(nil) + // getIDs returns an array of the IDs that are in the collection + access(all) fun getLeases(): [String] { + var list : [String] = [] + for key in self.leases.keys { + let lease = self.borrow(key) + if !lease.validate() { + continue + } + list.append(key) + } + return list + } - if lease.offerCallback == nil { - Debug.log("offer callback is empty") - }else { - Debug.log("offer callback is NOT empty") + access(all) fun getInvalidatedLeases(): [String] { + var list : [String] = [] + for key in self.leases.keys { + let lease = self.borrow(key) + if lease.validate() { + continue + } + list.append(key) } + return list + } - destroy oldAuction + // borrowNFT gets a reference to an NFT in the collection + // so that the caller can read its metadata and call its methods + access(all) fun borrow(_ name: String): &FIND.Lease { + return (&self.leases[name])! } - access(contract) fun cancelUserBid(_ name: String) { + access(LeaseOwner) fun borrowAuth(_ name: String): auth(LeaseOwner) &FIND.Lease { + return (&self.leases[name])! + } - if !self.leases.containsKey(name) { - panic("Invalid name=".concat(name)) - } + //borrow the auction + access(all) fun borrowAuction(_ name: String): &FIND.Auction { + return (&self.auctions[name])! + } - if self.auctions.containsKey(name) { - panic("Cannot cancel a bid that is in an auction=".concat(name)) - } - let lease= self.borrowAuth(name) + //This has to be here since you can only get this from a auth account and thus we ensure that you cannot use wrong paths + access(LeaseOwner) fun register(name: String, vault: @FlowToken.Vault){ + let profileCap = self.owner!.capabilities.get<&{Profile.Public}>(Profile.publicPath) + let leases= self.owner!.capabilities.get<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - if let callback = lease.offerCallback { + let network=FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath)! - let bidder= callback.address - let bidderProfile= getAccount(bidder).capabilities.borrow<&{Profile.Public}>(Profile.publicPath) - let bidderName=bidderProfile?.getName() - let bidderAvatar=bidderProfile?.getAvatar() - let owner=lease.owner!.address - let ownerName=lease.name - var amount : UFix64 = 0.0 - if callback.check() { - amount = callback.borrow()!.getBalance(name) - } - emit DirectOffer(name: name, uuid: lease.uuid, seller: owner, sellerName: ownerName, amount: amount, status: "cancel_rejected", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) + if !network.publicEnabled { + panic("Public registration is not enabled yet") } - lease.setCallback(nil) + network.register(name:name, vault: <- vault, profile: profileCap, leases: leases) } - access(contract) fun increaseBid(_ name: String, balance: UFix64) { - if !self.leases.containsKey(name) { - panic("Invalid name=".concat(name)) - } + //This has to be here since you can only get this from a auth account and thus we ensure that you cannot use wrong paths + access(LeaseOwner) fun registerDapper(merchAccount: Address, name: String, vault: @DapperUtilityCoin.Vault){ + let profileCap = self.owner!.capabilities.get<&{Profile.Public}>(Profile.publicPath) + let leases= self.owner!.capabilities.get<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - let lease = self.borrowAuth(name) + let network=FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath)! - if !lease.validate() { - panic("This is not a valid lease. Lease already expires and some other user registered it. Lease : ".concat(name)) + if !network.publicEnabled { + panic("Public registration is not enabled yet") } - let timestamp=Clock.time() + network.registerDapper(merchAccount: merchAccount, name:name, vault: <- vault, profile: profileCap, leases: leases) + } - if balance < lease.auctionMinBidIncrement { - panic("Increment should be greater than ".concat(lease.auctionMinBidIncrement.toString())) - } - if self.auctions.containsKey(name) { - let auction = self.borrowAuction(name) - if auction.endsAt < timestamp { - panic("Auction has ended") - } - auction.addBid(callback:auction.latestBidCallback, timestamp:timestamp, lease: lease) - return + access(LeaseOwner) fun cleanUpInvalidatedLease(_ name: String) { + let lease = self.borrowAuth(name) + if lease.validate() { + panic("This is a valid lease. You cannot clean this up. Lease : ".concat(name)) } + destroy <- self.leases.remove(key: name)! + } + } + //Create an empty lease collection that store your leases to a name + access(all) fun createEmptyLeaseCollection(): @FIND.LeaseCollection { + if let network = self.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath) { + return <- create LeaseCollection(networkCut:network.secondaryCut, networkWallet: network.wallet) + } + panic("Network is not set up") + } - let bidder= lease.offerCallback!.address - let bidderProfile= getAccount(bidder).capabilities.borrow<&{Profile.Public}>(Profile.publicPath) ?? panic("Create a profile before you make a bid") - let bidderName= bidderProfile.getName() - let bidderAvatar= bidderProfile.getAvatar() - let owner=lease.owner!.address - let ownerName=lease.name - let balance=lease.offerCallback!.borrow()?.getBalance(name) ?? panic("Bidder unlinked the bid collection capability. bidder address : ".concat(bidder.toString())) - Debug.log("Offer is at ".concat(balance.toString())) - if lease.salePrice == nil && lease.auctionStartPrice == nil{ - emit DirectOffer(name: name, uuid: lease.uuid, seller: owner, sellerName: ownerName, amount: balance, status: "active_offered", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - return - } + /* + Core network things + //=================================================================================================================== + */ + //a struct that represents a lease of a name in the network. + access(all) struct NetworkLease { + access(all) let registeredTime: UFix64 + access(all) var validUntil: UFix64 + access(all) var lockedUntil: UFix64 + access(all) var profile: Capability<&{Profile.Public}> + // This address is wrong for some account and can never be refered + access(all) var address: Address + access(all) var name: String + init( validUntil:UFix64, lockedUntil:UFix64, profile: Capability<&{Profile.Public}>, name: String) { + self.validUntil=validUntil + self.lockedUntil=lockedUntil + self.registeredTime=Clock.time() + self.profile=profile + self.address= profile.address + self.name=name + } - if lease.salePrice != nil && lease.salePrice != nil && balance >= lease.salePrice! { - self.fulfill(name) - } else if lease.auctionStartPrice != nil && balance >= lease.auctionStartPrice! { - self.startAuction(name) - } else { - emit DirectOffer(name: name, uuid: lease.uuid, seller: owner, sellerName: ownerName, amount: balance, status: "active_offered", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - } + access(all) fun setValidUntil(_ unit: UFix64) { + self.validUntil=unit + } + access(all) fun setLockedUntil(_ unit: UFix64) { + self.lockedUntil=unit } - access(contract) fun registerBid(name: String, callback: Capability<&BidCollection>) { - - if !self.leases.containsKey(name) { - panic("Invalid name=".concat(name)) - } - - let timestamp=Clock.time() - let lease = self.borrowAuth(name) - - if !lease.validate() { - panic("This is not a valid lease. Lease already expires and some other user registered it. Lease : ".concat(name)) - } - - if self.auctions.containsKey(name) { - let auction = self.borrowAuction(name) - - if auction.latestBidCallback.address == callback.address { - panic("You already have the latest bid on this item, use the incraseBid transaction") - } - if auction.endsAt < timestamp { - panic("Auction has ended") - } - auction.addBid(callback:callback, timestamp:timestamp, lease: lease) - return - } - - let balance=callback.borrow()?.getBalance(name) ?? panic("Bidder unlinked the bid collection capability. bidder address : ".concat(callback.address.toString())) - var previousBuyer:Address?=nil - if let cb= lease.offerCallback { - if cb.address == callback.address { - panic("You already have the latest bid on this item, use the incraseBid transaction") - } - let cbRef = cb.borrow() ?? panic("Bidder unlinked the bid collection capability. bidder address : ".concat(cb.address.toString())) - let currentBalance=cbRef.getBalance(name) - - Debug.log("currentBalance=".concat(currentBalance.toString()).concat(" new bid is at=").concat(balance.toString())) - if currentBalance >= balance { - panic("There is already a higher bid on this lease. Current bid is : ".concat(currentBalance.toString()).concat(" New bid is at : ").concat(balance.toString())) - } - previousBuyer=cb.address - cbRef.cancel(name) - } - - lease.setCallback(callback) - - - - let bidder= callback.address - let profile=getAccount(bidder).capabilities.borrow<&{Profile.Public}>(Profile.publicPath) - if profile == nil { - panic("Create a profile before you make a bid") - } - let bidderName= profile!.getName() - let bidderAvatar= profile!.getAvatar() - let owner=lease.owner!.address - let ownerName=lease.name - - var previousBuyerName:String?=nil - if let pb=previousBuyer { - previousBuyerName=FIND.reverseLookup(pb) - } - Debug.log("Balance of lease is at ".concat(balance.toString())) - if lease.salePrice == nil && lease.auctionStartPrice == nil { - Debug.log("Sale price not set") - emit DirectOffer(name: name, uuid:lease.uuid, seller: owner, sellerName: ownerName, amount: balance, status: "active_offered", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:previousBuyer, previousBuyerName:previousBuyerName) - return - } - - if lease.salePrice != nil && balance >= lease.salePrice! { - Debug.log("Direct sale!") - self.fulfill(name) - } else if lease.auctionStartPrice != nil && balance >= lease.auctionStartPrice! { - self.startAuction(name) - } else { - emit DirectOffer(name: name, uuid: lease.uuid, seller: owner, sellerName: ownerName, amount: balance, status: "active_offered", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:previousBuyer, previousBuyerName:previousBuyerName) - } - } - - //cancel will cancel and auction or reject a bid if no auction has started - access(AuctionOwner) fun cancel(_ name: String) { - - if !self.leases.containsKey(name) { - panic("Invalid name=".concat(name)) - } - - let lease = self.borrowAuth(name) - //if we have a callback there is no auction and it is a blind bid - if let cb= lease.offerCallback { - - let bidder= cb.address - let bidderProfile= getAccount(bidder).capabilities.borrow<&{Profile.Public}>(Profile.publicPath) - let bidderName= bidderProfile?.getName() - let bidderAvatar= bidderProfile?.getAvatar() - let owner=lease.owner!.address - let ownerName=lease.name - Debug.log("we have a blind bid so we cancel that") - let cbRef = cb.borrow() ?? panic("Bidder unlinked the bid collection capability. bidder address : ".concat(cb.address.toString())) - emit DirectOffer(name: name, uuid:lease.uuid, seller: owner, sellerName: ownerName, amount: cbRef.getBalance(name), status: "rejected", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - - cbRef.cancel(name) - lease.setCallback(nil) - } - - if self.auctions.containsKey(name) { - - let auction=self.borrowAuction(name) - let balance=auction.getBalance() - - let auctionEnded= auction.endsAt <= Clock.time() - var hasMetReservePrice= false - if lease.auctionReservePrice != nil && lease.auctionReservePrice! <= balance { - hasMetReservePrice=true - } - let price= lease.auctionReservePrice?.toString() ?? "" - //the auction has ended - Debug.log("Latest bid is ".concat(balance.toString()).concat(" reserve price is ").concat(price)) - if auctionEnded && hasMetReservePrice { - //&& lease.auctionReservePrice != nil && lease.auctionReservePrice! < balance { - panic("Cannot cancel finished auction, fulfill it instead") - } - - let bidder= auction.latestBidCallback.address - let bidderProfile= getAccount(bidder).capabilities.borrow<&{Profile.Public}>(Profile.publicPath) - let bidderName= bidderProfile?.getName() - let bidderAvatar= bidderProfile?.getAvatar() - let owner=lease.owner!.address - let ownerName=lease.name - - - let leaseInfo = self.getLease(name)! - - if auctionEnded { - emit EnglishAuction(name: name, uuid:lease.uuid, seller: owner, sellerName:ownerName, amount: balance, auctionReservePrice: lease.auctionReservePrice!, status: "cancel_reserved_not_met", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, endsAt: auction.endsAt, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - } else { - emit EnglishAuction(name: name, uuid:lease.uuid, seller: owner, sellerName:ownerName, amount: balance, auctionReservePrice: lease.auctionReservePrice!, status: "cancel_listing", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, endsAt: auction.endsAt, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - } - let cbRef = auction.latestBidCallback.borrow() ?? panic("Bidder unlinked the bid collection capability. bidder address : ".concat(bidder.toString())) - cbRef.cancel(name) - destroy <- self.auctions.remove(key: name)! - return - } - let owner=lease.owner!.address - let ownerName=lease.name - emit EnglishAuction(name: name, uuid:lease.uuid, seller: owner, sellerName:ownerName, amount: 0.0, auctionReservePrice: lease.auctionReservePrice!, status: "cancel_listing", vaultType:Type<@FUSD.Vault>().identifier, buyer:nil, buyerName:nil, buyerAvatar: nil, endsAt: nil, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - - } - - /// fulfillAuction wraps the fulfill method and ensure that only a finished auction can be fulfilled by anybody - access(all) fun fulfillAuction(_ name: String) { - if !self.leases.containsKey(name) { - panic("Invalid name=".concat(name)) - } - - if !self.auctions.containsKey(name) { - panic("Cannot fulfill sale that is not an auction=".concat(name)) - } - - return self.fulfill(name) - } - - access(LeaseOwner) fun fulfill(_ name: String) { - if !self.leases.containsKey(name) { - panic( "Invalid name=".concat(name)) - } - - let lease = self.borrowAuth(name) - - if !lease.validate() { - panic("This is not a valid lease. Lease already expires and some other user registered it. Lease : ".concat(name)) - } - - if lease.getLeaseStatus() == LeaseStatus.FREE { - panic("cannot fulfill sale name is now free") - } - - let oldProfile=lease.getProfile()! - - if let cb= lease.offerCallback { - let salePrice=lease.salePrice - let uuid=lease.uuid - let offer= cb.borrow()! - let newProfile= getAccount(cb.address).capabilities.get<&{Profile.Public}>(Profile.publicPath) - let avatar= newProfile.borrow()?.getAvatar() ?? panic("Create a profile before you fulfill a bid") - let soldFor=offer.getBalance(name) - - //move the token to the new profile - lease.move(profile: newProfile) - - if lease.salePrice == nil || lease.salePrice != soldFor { - emit DirectOffer(name: name, uuid: lease.uuid, seller: lease.owner!.address, sellerName: FIND.reverseLookup(lease.owner!.address), amount: soldFor, status: "sold", vaultType:Type<@FUSD.Vault>().identifier, buyer:newProfile.address, buyerName:FIND.reverseLookup(newProfile.address), buyerAvatar: avatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - } else { - emit Sale(name: name, uuid: lease.uuid, seller: lease.owner!.address, sellerName: FIND.reverseLookup(lease.owner!.address), amount: soldFor, status: "sold", vaultType:Type<@FUSD.Vault>().identifier, buyer:newProfile.address, buyerName:FIND.reverseLookup(newProfile.address), buyerAvatar: avatar, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil()) - } - - let token <- self.leases.remove(key: name)! - let vault <- offer.fulfillLease(<- token) - if self.networkCut != 0.0 { - let cutAmount= soldFor * self.networkCut - let networkWallet = self.networkWallet.borrow() ?? panic("The network wallet is not set up properly. Wallet address : ".concat(self.networkWallet.address.toString())) - networkWallet.deposit(from: <- vault.withdraw(amount: cutAmount)) - if salePrice == nil || salePrice != soldFor { - emit RoyaltyPaid(name: name, uuid: uuid, address: self.networkWallet.address, findName:FIND.reverseLookup(self.networkWallet.address), royaltyName:"Network", amount: cutAmount, vaultType:vault.getType().identifier, saleType: "DirectOffer") - } else { - emit RoyaltyPaid(name: name, uuid: uuid, address: self.networkWallet.address, findName:FIND.reverseLookup(self.networkWallet.address), royaltyName:"Network", amount: cutAmount, vaultType:vault.getType().identifier, saleType: "Sale") - } - } - - //why not use Profile to send money :P - oldProfile.deposit(from: <- vault) - return - } - - if !self.auctions.containsKey(name) { - panic("Name is not for auction name=".concat(name)) - } - - if self.borrowAuction(name).endsAt > Clock.time() { - panic("Auction has not ended yet") - } - - - let auctionRef=self.borrowAuction(name) - let soldFor=auctionRef.getBalance() - let reservePrice=lease.auctionReservePrice ?? 0.0 - - if reservePrice > soldFor { - self.cancel(name) - return - } - let newProfile= getAccount(auctionRef.latestBidCallback.address).capabilities.get<&{Profile.Public}>(Profile.publicPath) - let avatar= newProfile.borrow()?.getAvatar() ?? panic("Create a profile before you fulfill a bid") - - - - let uuid=lease.uuid - //move the token to the new profile - lease.move(profile: newProfile) - emit EnglishAuction(name: name, uuid:lease.uuid, seller: lease.owner!.address, sellerName:FIND.reverseLookup(lease.owner!.address), amount: soldFor, auctionReservePrice: lease.auctionReservePrice!, status: "sold", vaultType:Type<@FUSD.Vault>().identifier, buyer:newProfile.address, buyerName:FIND.reverseLookup(newProfile.address), buyerAvatar: avatar, endsAt: self.borrowAuction(name).endsAt, validUntil: lease.getLeaseExpireTime(), lockedUntil: lease.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - let auction <- self.auctions.remove(key: name)! - - let token <- self.leases.remove(key: name)! - - let cbRef = auction.latestBidCallback.borrow() ?? panic("Bidder unlinked the bid collection capability. bidder address : ".concat(auction.latestBidCallback.address.toString())) - - let vault <- cbRef.fulfillLease(<- token) - if self.networkCut != 0.0 { - let cutAmount= soldFor * self.networkCut - let networkWallet = self.networkWallet.borrow() ?? panic("The network wallet is not set up properly. Wallet address : ".concat(self.networkWallet.address.toString())) - networkWallet.deposit(from: <- vault.withdraw(amount: cutAmount)) - emit RoyaltyPaid(name: name, uuid: uuid, address: self.networkWallet.address, findName:FIND.reverseLookup(self.networkWallet.address), royaltyName:"Network", amount: cutAmount, vaultType:vault.getType().identifier, saleType: "EnglishAuction") - } - - //why not use FIND to send money :P - oldProfile.deposit(from: <- vault) - destroy auction - - } - - access(LeaseOwner) fun listForAuction(name :String, auctionStartPrice: UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64) { - - if !self.leases.containsKey(name) { - panic("Cannot list name for sale that is not registered to you name=".concat(name)) - } - - let tokenRef = self.borrowAuth(name) - - if !tokenRef.validate() { - panic("This is not a valid lease. Lease already expires and some other user registered it. Lease : ".concat(name)) - } - - //if we have a callback there is no auction and it is a blind bid - if let cb= tokenRef.offerCallback { - let bidder= cb.address - let bidderProfile= getAccount(bidder).capabilities.get<&{Profile.Public}>(Profile.publicPath).borrow() - let bidderName= bidderProfile?.getName() - let bidderAvatar= bidderProfile?.getAvatar() - let owner=tokenRef.owner!.address - let ownerName=tokenRef.name - Debug.log("we have a blind bid so we cancel that") - let cbRef = cb.borrow() ?? panic("Bidder unlinked the bid collection capability. bidder address : ".concat(bidder.toString())) - emit DirectOffer(name: name, uuid:tokenRef.uuid, seller: owner, sellerName: ownerName, amount: cbRef.getBalance(name), status: "rejected", vaultType:Type<@FUSD.Vault>().identifier, buyer:bidder, buyerName:bidderName, buyerAvatar: bidderAvatar, validUntil: tokenRef.getLeaseExpireTime(), lockedUntil: tokenRef.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - cbRef.cancel(name) - tokenRef.setCallback(nil) - } - - tokenRef.setStartAuctionPrice(auctionStartPrice) - tokenRef.setReservePrice(auctionReservePrice) - tokenRef.setAuctionDuration(auctionDuration) - tokenRef.setExtentionOnLateBid(auctionExtensionOnLateBid) - emit EnglishAuction(name: name, uuid: tokenRef.uuid, seller: self.owner!.address, sellerName:FIND.reverseLookup(self.owner!.address), amount: tokenRef.auctionStartPrice!, auctionReservePrice: tokenRef.auctionReservePrice!, status: "active_listed", vaultType:Type<@FUSD.Vault>().identifier, buyer:nil, buyerName:nil, buyerAvatar: nil, endsAt: nil, validUntil: tokenRef.getLeaseExpireTime(), lockedUntil: tokenRef.getLeaseLockedUntil(), previousBuyer:nil, previousBuyerName:nil) - } - - access(LeaseOwner) fun listForSale(name :String, directSellPrice:UFix64) { - if !self.leases.containsKey(name) { - panic("Cannot list name for sale that is not registered to you name=".concat(name)) - } - - let tokenRef = self.borrowAuth(name) - - if !tokenRef.validate() { - panic("This is not a valid lease. Lease already expires and some other user registered it. Lease : ".concat(name)) - } - - tokenRef.setSalePrice(directSellPrice) - emit Sale(name: name, uuid: tokenRef.uuid, seller: self.owner!.address, sellerName: FIND.reverseLookup(self.owner!.address), amount: tokenRef.salePrice!, status: "active_listed", vaultType:Type<@FUSD.Vault>().identifier, buyer:nil, buyerName:nil, buyerAvatar: nil, validUntil: tokenRef.getLeaseExpireTime(), lockedUntil: tokenRef.getLeaseLockedUntil()) - } - - - //keep this - access(all) fun delistAuction(_ name: String) { - - if !self.leases.containsKey(name) { - panic("Cannot delist name for sale that is not registered to you name=".concat(name)) - } - - let tokenRef = self.borrowAuth(name) - - tokenRef.setStartAuctionPrice(nil) - tokenRef.setReservePrice(nil) - } - - - //keep this - access(all) fun delistSale(_ name: String) { - if !self.leases.containsKey(name) { - panic("Cannot list name for sale that is not registered to you name=".concat(name)) - } - - let tokenRef = self.borrowAuth(name) - emit Sale(name: name, uuid:tokenRef.uuid, seller: self.owner!.address, sellerName: FIND.reverseLookup(self.owner!.address), amount: tokenRef.salePrice!, status: "cancel", vaultType:Type<@FUSD.Vault>().identifier, buyer:nil, buyerName:nil, buyerAvatar: nil, validUntil: tokenRef.getLeaseExpireTime(), lockedUntil: tokenRef.getLeaseLockedUntil()) - tokenRef.setSalePrice(nil) - } - - access(LeaseOwner) fun move(name: String, profile: Capability<&{Profile.Public}>, to: Capability<&LeaseCollection>) { - - let lease = self.borrowAuth(name) - if !lease.validate() { - panic("This is not a valid lease. Lease already expires and some other user registered it. Lease : ".concat(name)) - } - - let token <- self.leases.remove(key: name) ?? panic("missing NFT") - emit Moved(name: name, previousOwner:self.owner!.address, newOwner: profile.address, validUntil: token.getLeaseExpireTime(), lockedUntil: token.getLeaseLockedUntil()) - token.move(profile: profile) - let walletRef = to.borrow() ?? panic("The receiver capability is not valid. wallet address : ".concat(to.address.toString())) - walletRef.deposit(token: <- token) - - } - - //depoit a lease token into the lease collection, not available from the outside - access(contract) fun deposit(token: @FIND.Lease) { - // add the new token to the dictionary which removes the old one - let oldToken <- self.leases[token.name] <- token - - destroy oldToken - } - - // getIDs returns an array of the IDs that are in the collection - access(all) fun getLeases(): [String] { - var list : [String] = [] - for key in self.leases.keys { - let lease = self.borrow(key) - if !lease.validate() { - continue - } - list.append(key) - } - return list - } - - access(all) fun getInvalidatedLeases(): [String] { - var list : [String] = [] - for key in self.leases.keys { - let lease = self.borrow(key) - if lease.validate() { - continue - } - list.append(key) - } - return list - } - - // borrowNFT gets a reference to an NFT in the collection - // so that the caller can read its metadata and call its methods - access(all) fun borrow(_ name: String): &FIND.Lease { - return (&self.leases[name])! - } - - access(LeaseOwner) fun borrowAuth(_ name: String): auth(LeaseOwner) &FIND.Lease { - return (&self.leases[name])! - } - - //borrow the auction - access(all) fun borrowAuction(_ name: String): &FIND.Auction { - return (&self.auctions[name])! - } - - - // //TODO test - // access(LeaseOwner) fun registerUSDC(name: String, vault: @FiatToken.Vault){ - // let profileCap = self.owner!.capabilities.get<&{Profile.Public}>(Profile.publicPath) - // let leases= self.owner!.capabilities.get<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - - // let network=FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath)! - - // if !network.publicEnabled { - // panic("Public registration is not enabled yet") - // } - - // network.registerUSDC(name:name, vault: <- vault, profile: profileCap, leases: leases) - // } - - - //This has to be here since you can only get this from a auth account and thus we ensure that you cannot use wrong paths - access(LeaseOwner) fun register(name: String, vault: @FUSD.Vault){ - let profileCap = self.owner!.capabilities.get<&{Profile.Public}>(Profile.publicPath) - let leases= self.owner!.capabilities.get<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - - let network=FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath)! - - if !network.publicEnabled { - panic("Public registration is not enabled yet") - } - - network.register(name:name, vault: <- vault, profile: profileCap, leases: leases) - } - - //This has to be here since you can only get this from a auth account and thus we ensure that you cannot use wrong paths - access(LeaseOwner) fun registerDapper(merchAccount: Address, name: String, vault: @DapperUtilityCoin.Vault){ - let profileCap = self.owner!.capabilities.get<&{Profile.Public}>(Profile.publicPath) - let leases= self.owner!.capabilities.get<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - - let network=FIND.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath)! - - if !network.publicEnabled { - panic("Public registration is not enabled yet") - } - - network.registerDapper(merchAccount: merchAccount, name:name, vault: <- vault, profile: profileCap, leases: leases) - } - - access(LeaseOwner) fun cleanUpInvalidatedLease(_ name: String) { - let lease = self.borrowAuth(name) - if lease.validate() { - panic("This is a valid lease. You cannot clean this up. Lease : ".concat(name)) - } - destroy <- self.leases.remove(key: name)! - } - } - - //Create an empty lease collection that store your leases to a name - access(all) fun createEmptyLeaseCollection(): @FIND.LeaseCollection { - if let network = self.account.storage.borrow<&Network>(from: FIND.NetworkStoragePath) { - return <- create LeaseCollection(networkCut:network.secondaryCut, networkWallet: network.wallet) - } - panic("Network is not set up") - } - - - - /* - Core network things - //=================================================================================================================== - */ - //a struct that represents a lease of a name in the network. - access(all) struct NetworkLease { - access(all) let registeredTime: UFix64 - access(all) var validUntil: UFix64 - access(all) var lockedUntil: UFix64 - access(all) var profile: Capability<&{Profile.Public}> - // This address is wrong for some account and can never be refered - access(all) var address: Address - access(all) var name: String - - init( validUntil:UFix64, lockedUntil:UFix64, profile: Capability<&{Profile.Public}>, name: String) { - self.validUntil=validUntil - self.lockedUntil=lockedUntil - self.registeredTime=Clock.time() - self.profile=profile - self.address= profile.address - self.name=name - } - - access(all) fun setValidUntil(_ unit: UFix64) { - self.validUntil=unit - } - - access(all) fun setLockedUntil(_ unit: UFix64) { - self.lockedUntil=unit - } - - access(all) fun status() : LeaseStatus { - let time=Clock.time() + access(all) fun status() : LeaseStatus { + let time=Clock.time() if time >= self.lockedUntil { return LeaseStatus.FREE @@ -1514,14 +946,11 @@ access(all) contract FIND { self.lengthPrices=additionalPrices } - - //TODO: add support for Fiat - //this method is only called from a lease, and only the owner has that capability - access(contract) fun renew(name: String, vault: @FUSD.Vault) { + access(contract) fun renew(name: String, vault: @FlowToken.Vault) { if let lease= self.profiles[name] { - let cost= self.calculateCost(name) + let cost= FIND.calculateCostInFlow(name) if vault.balance != cost { - panic("Vault did not contain ".concat(cost.toString()).concat(" amount of FUSD")) + panic("Vault did not contain ".concat(cost.toString()).concat(" amount of Flow")) } let walletRef = self.wallet.borrow() ?? panic("The receiver capability is invalid. Wallet address : ".concat(self.wallet.address.toString())) walletRef.deposit(from: <- vault) @@ -1592,39 +1021,8 @@ access(all) contract FIND { panic("Could not find profile with name=".concat(name)) } - //TODO test - // access(all) fun registerUSDC(name: String, vault: @FiatToken.Vault, profile: Capability<&{Profile.Public}>, leases: Capability<&{LeaseCollectionPublic}>) { - - // if name.length < 3 { - // panic( "A FIND name has to be minimum 3 letters long") - // } - - // let nameStatus=self.readStatus(name) - // if nameStatus.status == LeaseStatus.TAKEN { - // panic("Name already registered") - // } - - // //if we have a locked profile that is not owned by the same identity then panic - // if nameStatus.status == LeaseStatus.LOCKED { - // panic("Name is locked") - // } - - // let cost= self.calculateCost(name) - // if vault.balance != cost { - // panic("Vault did not contain ".concat(cost.toString()).concat(" amount of FUSD")) - // } - - // let address=self.wallet.address - // let account=getAccount(address) - // let usdcCap = account.capabilities.get<&{FungibleToken.Receiver}>(FiatToken.VaultReceiverPubPath) - // let usdcReceiver = usdcCap.borrow() ?? panic("cound not find usdc vault receiver for address".concat(self.wallet.address.toString())) - // usdcReceiver.deposit(from: <- vault) - - // self.internal_register(name: name, profile: profile, leases: leases) - // } - //everybody can call register, normally done through the convenience method in the contract - access(all) fun register(name: String, vault: @FUSD.Vault, profile: Capability<&{Profile.Public}>, leases: Capability<&{LeaseCollectionPublic}>) { + access(all) fun register(name: String, vault: @FlowToken.Vault, profile: Capability<&{Profile.Public}>, leases: Capability<&{LeaseCollectionPublic}>) { if name.length < 3 { panic( "A FIND name has to be minimum 3 letters long") @@ -1640,9 +1038,9 @@ access(all) contract FIND { panic("Name is locked") } - let cost= self.calculateCost(name) + let cost= FIND.calculateCostInFlow(name) if vault.balance != cost { - panic("Vault did not contain ".concat(cost.toString()).concat(" amount of FUSD")) + panic("Vault did not contain ".concat(cost.toString()).concat(" amount of Flow")) } self.wallet.borrow()!.deposit(from: <- vault) @@ -1788,192 +1186,6 @@ access(all) contract FIND { } - /* - ========================================================================== - Bids are a collection/resource for storing the bids bidder made on leases - ========================================================================== - */ - - //Struct that is used to return information about bids - access(all) struct BidInfo{ - access(all) let name: String - access(all) let type: String - access(all) let amount: UFix64 - access(all) let timestamp: UFix64 - access(all) let lease: LeaseInformation? - - init(name: String, amount: UFix64, timestamp: UFix64, type: String, lease: LeaseInformation?) { - self.name=name - self.amount=amount - self.timestamp=timestamp - self.type=type - self.lease=lease - } - } - - access(all) resource Bid { - access(contract) let from: Capability<&LeaseCollection> - access(contract) let name: String - access(contract) var type: String - access(contract) let vault: @FUSD.Vault - access(contract) var bidAt: UFix64 - - init(from: Capability<&LeaseCollection>, name: String, vault: @FUSD.Vault){ - self.vault <- vault - self.name=name - self.from=from - self.type="blind" - self.bidAt=Clock.time() - } - - access(contract) fun setType(_ type: String) { - self.type=type - } - access(contract) fun setBidAt(_ time: UFix64) { - self.bidAt=time - } - - } - - access(all) resource interface BidCollectionPublic { - access(all) fun getBids() : [BidInfo] - access(all) fun getBalance(_ name: String) : UFix64 - access(contract) fun fulfillLease(_ token: @FIND.Lease) : @{FungibleToken.Vault} - access(contract) fun cancel(_ name: String) - access(contract) fun setBidType(name: String, type: String) - } - - //A collection stored for bidders/buyers - access(all) resource BidCollection: BidCollectionPublic { - - access(contract) var bids : @{String: Bid} - access(contract) let receiver: Capability<&{FungibleToken.Receiver}> - access(contract) let leases: Capability<&LeaseCollection> - - init(receiver: Capability<&{FungibleToken.Receiver}>, leases: Capability<&LeaseCollection>) { - self.bids <- {} - self.receiver=receiver - self.leases=leases - } - - //called from lease when auction is ended - //if purchase if fulfilled then we deposit money back into vault we get passed along and token into your own leases collection - access(contract) fun fulfillLease(_ token: @FIND.Lease) : @{FungibleToken.Vault}{ - if !self.leases.check() { - panic("The lease collection capability is invalid.") - } - let bid <- self.bids.remove(key: token.name) ?? panic("missing bid") - - let vaultRef = &bid.vault as auth (FungibleToken.Withdraw) &{FungibleToken.Vault} - token.setSalePrice(nil) - token.setCallback(nil) - token.setReservePrice(nil) - token.setStartAuctionPrice(nil) - self.leases.borrow()!.deposit(token: <- token) - let vault <- vaultRef.withdraw(amount: vaultRef.balance) - destroy bid - return <- vault - } - - //called from lease when things are canceled - //if the bid is canceled from seller then we move the vault tokens back into your vault - access(contract) fun cancel(_ name: String) { - if !self.receiver.check() { - panic("This user does not have receiving vault set up. User: ".concat(self.owner!.address.toString())) - } - let bid <- self.bids.remove(key: name) ?? panic("missing bid") - let vaultRef = &bid.vault as auth (FungibleToken.Withdraw) &{FungibleToken.Vault} - self.receiver.borrow()!.deposit(from: <- vaultRef.withdraw(amount: vaultRef.balance)) - destroy bid - } - - access(all) fun getBids() : [BidInfo] { - var bidInfo: [BidInfo] = [] - for id in self.bids.keys { - let bid = self.borrowBid(id) - let leaseCollection= bid.from.borrow() ?? panic("Could not borrow lease bid from owner of name=".concat(bid.name)) - bidInfo.append(BidInfo(name: bid.name, amount: bid.vault.balance, timestamp: bid.bidAt, type: bid.type, lease: leaseCollection.getLease(bid.name))) - } - return bidInfo - } - - //make a bid on a name - access(all) fun bid(name: String, vault: @FUSD.Vault) { - let nameStatus=FIND.status(name) - if nameStatus.status == LeaseStatus.FREE { - panic("cannot bid on name that is free") - } - - if self.owner!.address == nameStatus.owner { - panic("cannot bid on your own name") - } - - let fromCap=getAccount(nameStatus.owner!).capabilities.get<&LeaseCollection>(FIND.LeasePublicPath) - - let bid <- create Bid(from: fromCap, name:name, vault: <- vault) - let leaseCollection= fromCap.borrow() ?? panic("Could not borrow lease bid from owner of name=".concat(name)) - - - let callbackCapability =self.owner!.capabilities.get<&BidCollection>(FIND.BidPublicPath) - let oldToken <- self.bids[bid.name] <- bid - //send info to leaseCollection - destroy oldToken - leaseCollection.registerBid(name: name, callback: callbackCapability) - } - - //increase a bid, will not work if the auction has already started - access(all) fun increaseBid(name: String, vault: @{FungibleToken.Vault}) { - let nameStatus=FIND.status(name) - if nameStatus.status == LeaseStatus.FREE { - panic("cannot increaseBid on name that is free") - } - let seller=getAccount(nameStatus.owner!).capabilities.get<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - let balance = vault.balance - let bid =self.borrowBid(name) - bid.setBidAt(Clock.time()) - bid.vault.deposit(from: <- vault) - - let from=getAccount(nameStatus.owner!).capabilities.get<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath).borrow() - if from == nil { - panic("The seller unlinked the lease collection capability. seller address : ".concat(nameStatus.owner!.toString())) - } - from!.increaseBid(name, balance: balance) - } - - //cancel a bid, will panic if called after auction has started - access(all) fun cancelBid(_ name: String) { - - let nameStatus=FIND.status(name) - if nameStatus.status == LeaseStatus.FREE { - self.cancel(name) - return - } - let from=getAccount(nameStatus.owner!).capabilities.borrow<&{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - if from == nil { - panic("The seller unlinked the lease collection capability. seller address : ".concat(nameStatus.owner!.toString())) - } - from!.cancelUserBid(name) - self.cancel(name) - } - - access(all) fun borrowBid(_ name: String): &Bid { - return (&self.bids[name])! - } - - access(contract) fun setBidType(name: String, type: String) { - let bid= self.borrowBid(name) - bid.setType(type) - } - - access(all) fun getBalance(_ name: String) : UFix64 { - let bid= self.borrowBid(name) - return bid.vault.balance - } - } - - access(all) fun createEmptyBidCollection(receiver: Capability<&{FungibleToken.Receiver}>, leases: Capability<&LeaseCollection>) : @BidCollection { - return <- create BidCollection(receiver: receiver, leases: leases) - } access(all) fun validateFindName(_ value: String) : Bool { if value.length < 3 || value.length > 16 { @@ -2065,6 +1277,22 @@ access(all) contract FIND { } } + + access(account) fun getFlowUSDOracleAddress() : Address { + // If only find can sign the trxns and call this function, then we do not have to check the address passed in. + // Otherwise, would it be wiser if we hard code the address here? + if FIND.account.address == 0x097bafa4e0b48eef { + // This is for mainnet + return 0xe385412159992e11 + } else if FIND.account.address == 0x35717efbbce11c74 { + // This is for testnet + return 0xcbdb5a7b89c3c844 + } else { + //otherwise on emulator we use same account as FIND + return self.account.address + } + } + access(account) fun getMerchantAddress() : Address { // If only find can sign the trxns and call this function, then we do not have to check the address passed in. // Otherwise, would it be wiser if we hard code the address here? @@ -2134,4 +1362,125 @@ access(all) contract FIND { ) self.account.storage.save(<-network, to: FIND.NetworkStoragePath) } + + + ////////////////////////////////////////////////////////////////////// + // DEPRECATED + ////////////////////////////////////////////////////////////////////// + + + /* This code is dead, it still needs to be here, but it is not in use anymore */ + access(all) event Sold() + access(all) event SoldAuction() + access(all) event DirectOfferRejected() + access(all) event DirectOfferCanceled() + access(all) event AuctionStarted() + access(all) event AuctionCanceled() + access(all) event AuctionBid() + access(all) event AuctionCanceledReservePrice() + access(all) event ForSale() + access(all) event ForAuction() + + // Deprecated in testnet + access(all) event TokensRewarded() + access(all) event TokensCanNotBeRewarded() + + /// Emitted when a name is explicistly put up for sale + access(all) event Sale(name: String, uuid:UInt64, seller: Address, sellerName: String?, amount: UFix64, status: String, vaultType:String, buyer:Address?, buyerName:String?, buyerAvatar: String?, validUntil: UFix64, lockedUntil: UFix64) + + /// Emitted when an name is put up for on-demand auction + access(all) event EnglishAuction(name: String, uuid:UInt64, seller: Address, sellerName:String?, amount: UFix64, auctionReservePrice: UFix64, status: String, vaultType:String, buyer:Address?, buyerName:String?, buyerAvatar: String?, endsAt: UFix64?, validUntil: UFix64, lockedUntil: UFix64, previousBuyer:Address?, previousBuyerName:String?) + + /// Emitted if a bid occurs at a name that is too low or not for sale + access(all) event DirectOffer(name: String, uuid:UInt64, seller: Address, sellerName: String?, amount: UFix64, status: String, vaultType:String, buyer:Address?, buyerName:String?, buyerAvatar: String?, validUntil: UFix64, lockedUntil: UFix64, previousBuyer:Address?, previousBuyerName:String?) + + access(all) event RoyaltyPaid(name: String, uuid: UInt64, address: Address, findName:String?, royaltyName:String, amount: UFix64, vaultType:String, saleType: String) + + //store bids made by a bidder to somebody elses leases + access(all) let BidPublicPath: PublicPath + access(all) let BidStoragePath: StoragePath + + /* An Auction for a lease */ + access(all) resource Auction { + access(contract) var endsAt: UFix64 + access(contract) var startedAt: UFix64 + access(contract) let extendOnLateBid: UFix64 + access(contract) var latestBidCallback: Capability<&BidCollection> + access(contract) let name: String + + init(endsAt: UFix64, startedAt: UFix64, extendOnLateBid: UFix64, latestBidCallback: Capability<&BidCollection>, name: String) { + + if startedAt >= endsAt { + panic("Cannot start before it will end") + } + if extendOnLateBid == 0.0 { + panic("Extends on late bid must be a non zero value") + } + self.endsAt=endsAt + self.startedAt=startedAt + self.extendOnLateBid=extendOnLateBid + self.latestBidCallback=latestBidCallback + self.name=name + } + + } + + + /* + ========================================================================== + Bids are a collection/resource for storing the bids bidder made on leases + ========================================================================== + */ + + //Struct that is used to return information about bids + access(all) struct BidInfo{ + access(all) let name: String + access(all) let type: String + access(all) let amount: UFix64 + access(all) let timestamp: UFix64 + access(all) let lease: LeaseInformation? + + init(name: String, amount: UFix64, timestamp: UFix64, type: String, lease: LeaseInformation?) { + self.name=name + self.amount=amount + self.timestamp=timestamp + self.type=type + self.lease=lease + } + } + + access(all) resource Bid { + access(contract) let from: Capability<&LeaseCollection> + access(contract) let name: String + access(contract) var type: String + access(contract) let vault: @FUSD.Vault + access(contract) var bidAt: UFix64 + + init(from: Capability<&LeaseCollection>, name: String, vault: @FUSD.Vault){ + self.vault <- vault + self.name=name + self.from=from + self.type="blind" + self.bidAt=Clock.time() + } + } + + access(all) resource interface BidCollectionPublic { + } + + //A collection stored for bidders/buyers + access(all) resource BidCollection: BidCollectionPublic { + + access(contract) var bids : @{String: Bid} + access(contract) let receiver: Capability<&{FungibleToken.Receiver}> + access(contract) let leases: Capability<&LeaseCollection> + + init(receiver: Capability<&{FungibleToken.Receiver}>, leases: Capability<&LeaseCollection>) { + self.bids <- {} + self.receiver=receiver + self.leases=leases + } + + } + } diff --git a/contracts/community/PublicPriceOracle.cdc b/contracts/community/PublicPriceOracle.cdc new file mode 100644 index 00000000..93b2ff84 --- /dev/null +++ b/contracts/community/PublicPriceOracle.cdc @@ -0,0 +1,28 @@ +/** + +# This contract provides public oracle data sourced from the multi-node PriceOracle contracts of Increment. + +# Anyone can access price data directly with getLatestPrice() & getLatestBlockHeight(), no whitelist needed. Check example here: https://docs.increment.fi/protocols/decentralized-price-feed-oracle/using-price-feeds + +# Admin controls what PriceOracles are exposed publicly. + +# Author: Increment Labs + +THIS is a local stub for testing +*/ + + +access(all) contract PublicPriceOracle { + + access(all) view fun getLatestPrice(oracleAddr: Address): UFix64 { + return 0.5 + } + + /// Get the block height at the time of the latest update. + /// + access(all) view fun getLatestBlockHeight(oracleAddr: Address): UInt64 { + return getCurrentBlock().height + } + + +} diff --git a/find_test.go b/find_test.go index 944f47f0..a743a064 100644 --- a/find_test.go +++ b/find_test.go @@ -28,15 +28,15 @@ func TestFIND(t *testing.T) { otu.O.Tx("register", WithSigner("user1"), WithArg("name", "usr"), - WithArg("amount", 500.0), - ).AssertFailure(t, "Amount withdrawn must be less than or equal than the balance of the Vault") + WithArg("maxAmount", 1000.0), + ).AssertFailure(t, "Balance of vault is not high enough") }) ot.Run(t, "Should get error if you try to register a name that is too short", func(t *testing.T) { otu.O.Tx("register", WithSigner("user1"), WithArg("name", "ur"), - WithArg("amount", 5.0), + WithArg("maxAmount", 10.0), ).AssertFailure(t, "A FIND name has to be lower-cased alphanumeric or dashes and between 3 and 16 characters") }) @@ -44,7 +44,7 @@ func TestFIND(t *testing.T) { otu.O.Tx("register", WithSigner("user1"), WithArg("name", "user1"), - WithArg("amount", 5.0), + WithArg("maxAmount", 10.0), ).AssertFailure(t, "Name already registered") }) @@ -250,9 +250,9 @@ access(all) fun main(name: String) : Address? { WithSigner("user2"), WithArg("name", "user2"), WithArg("addon", "forge"), - WithArg("amount", 10.0), + WithArg("maxAmount", 10.0), ). - AssertFailure(t, "Expect 50.00000000 FUSD for forge addon") + AssertFailure(t, "You have not sent in enough max flow") }) ot.Run(t, "Should be able to buy addons that are on Network", func(t *testing.T) { @@ -264,7 +264,7 @@ access(all) fun main(name: String) : Address? { WithSigner("user1"), WithArg("name", "user1"), WithArg("addon", "foo"), - WithArg("amount", 10.0), + WithArg("maxAmount", 10.0), ). AssertFailure(t, "This addon is not available.") }) @@ -571,67 +571,6 @@ access(all) fun main(name: String) : Address? { }`)) }) - ot.Run(t, "Should not be able to list old leases for sale", func(t *testing.T) { - otu.expireLease().expireLease().tickClock(2.0) - // should be able to list name for sale - otu.O.Tx("listNameForSale", - WithSigner("user1"), - WithArg("name", "user1"), - WithArg("directSellPrice", 10.0), - ).AssertFailure(t, "This is not a valid lease") - }) - - ot.Run(t, "Should be able to list lease for auction", func(t *testing.T) { - otu.O.Tx("listNameForAuction", - WithSigner("user1"), - WithArg("name", "user1"), - WithArg("auctionStartPrice", 5.0), - WithArg("auctionReservePrice", 20.0), - WithArg("auctionDuration", auctionDurationFloat), - WithArg("auctionExtensionOnLateBid", 300.0), - ).AssertSuccess(t) - }) - - ot.Run(t, "Should not be able to list old lease for auction", func(t *testing.T) { - otu.expireLease().expireLease().tickClock(2.0) - otu.O.Tx("listNameForAuction", - WithSigner("user1"), - WithArg("name", "user1"), - WithArg("auctionStartPrice", 5.0), - WithArg("auctionReservePrice", 20.0), - WithArg("auctionDuration", auctionDurationFloat), - WithArg("auctionExtensionOnLateBid", 300.0), - ).AssertFailure(t, "This is not a valid lease") - }) - - ot.Run(t, "Should be able to delist old leases for sale", func(t *testing.T) { - otu.listNameForSale("user1", "user1") - otu.expireLease().expireLease().tickClock(2.0) - - otu.O.Tx("delistNameSale", - WithSigner("user1"), - WithArg("names", []string{"user1"}), - ). - AssertSuccess(t) - }) - - ot.Run(t, "Should be able to delist old leases for auction", func(t *testing.T) { - otu.O.Tx("listNameForAuction", - WithSigner("user1"), - WithArg("name", "user1"), - WithArg("auctionStartPrice", 5.0), - WithArg("auctionReservePrice", 20.0), - WithArg("auctionDuration", auctionDurationFloat), - WithArg("auctionExtensionOnLateBid", 300.0), - ).AssertSuccess(t) - - otu.expireLease().expireLease().tickClock(2.0) - otu.O.Tx("cancelNameAuction", - WithSigner("user1"), - WithArg("names", []string{"user1"}), - ).AssertSuccess(t) - }) - ot.Run(t, "Should be able to cleanup invalid leases", func(t *testing.T) { otu.O.Tx("cleanUpInvalidatedLease", WithSigner("user1"), @@ -647,21 +586,4 @@ access(all) fun main(name: String) : Address? { ).AssertSuccess(t) }) - /* -* commented out due to circle not staging - ot.Run(t, "Should be able to register a name with usdc", func(t *testing.T) { - otu.O.Tx("registerUSDC", - WithSigner("user1"), - WithArg("name", "fooobar"), - WithArg("amount", 5.0), - ).AssertSuccess(t). - AssertEvent(otu.T, "FIND.Register", map[string]interface{}{ - "name": "fooobar", - }). - AssertEvent(otu.T, "FiatToken.TokensDeposited", map[string]interface{}{ - "amount": 5.0, - "to": otu.O.Address("find-admin"), - }) - }) - */ } diff --git a/flow.json b/flow.json index aefc4156..998d98b9 100644 --- a/flow.json +++ b/flow.json @@ -384,7 +384,8 @@ "NFTCatalogAdmin", "LostAndFound", "LostAndFoundHelper", - "FeeEstimator" + "FeeEstimator", + "PublicPriceOracle" ], "emulator-dapper": [ "DapperUtilityCoin", diff --git a/generated_experiences_test.go b/generated_experiences_test.go index 1fabe4bb..a129053b 100644 --- a/generated_experiences_test.go +++ b/generated_experiences_test.go @@ -8,7 +8,6 @@ import ( "github.com/hexops/autogold" ) - func TestGeneratedExperiences(t *testing.T) { otu := &OverflowTestUtils{T: t, O: ot.O} @@ -153,7 +152,7 @@ func TestGeneratedExperiences(t *testing.T) { "A.f8d6e0586b0a20c7.MetadataViews.Royalties": autogold.Want("Royalties", map[string]interface{}{"cutInfos": []interface{}{map[string]interface{}{"cut": 0.1, "description": "Royalty", "receiver": map[string]interface{}{ "address": "0x192440c99cb17282", "borrowType": "&{A.ee82856bf20e2aa6.FungibleToken.Receiver}", - "id": 10, + "id": 9, }}}}), "A.f8d6e0586b0a20c7.MetadataViews.Editions": autogold.Want("Editions", map[string]interface{}{"infoList": []interface{}{map[string]interface{}{"max": 2, "name": "generatedexperiences", "number": 1}}}), "A.f8d6e0586b0a20c7.MetadataViews.Traits": autogold.Want("Traits", map[string]interface{}{"traits": []interface{}{map[string]interface{}{"displayType": "String", "name": "Artist", "value": "Artist"}}}), diff --git a/lease_market_auction_soft_flow_test.go b/lease_market_auction_soft_flow_test.go new file mode 100644 index 00000000..6f3c22e7 --- /dev/null +++ b/lease_market_auction_soft_flow_test.go @@ -0,0 +1,378 @@ +package test_main + +import ( + "testing" + + . "github.com/bjartek/overflow/v2" +) + +func TestLeaseMarketAuctionSoft(t *testing.T) { + otu := &OverflowTestUtils{T: t, O: ot.O} + + price := 10.0 + preIncrement := 5.0 + + eventIdentifier := otu.identifier("FindLeaseMarketAuctionSoft", "EnglishAuction") + royaltyIdentifier := otu.identifier("FindLeaseMarket", "RoyaltyPaid") + + bidTx := otu.O.TxFileNameFN("bidLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithArg("leaseName", "user5"), + WithArg("amount", price), + ) + + increaseBidTx := otu.O.TxFileNameFN("increaseBidLeaseMarketAuctionSoft", + WithSigner("user6"), + WithArg("leaseName", "user5"), + WithArg("amount", preIncrement), + ) + + listTx := otu.O.TxFileNameFN("listLeaseForAuctionSoftDapper", + WithSigner("user5"), + WithArg("leaseName", "user5"), + WithArg("ftAliasOrIdentifier", "FUT"), + WithArg("price", price), + WithArg("auctionReservePrice", price+5.0), + WithArg("auctionDuration", 300.0), + WithArg("auctionExtensionOnLateBid", 60.0), + WithArg("minimumBidIncrement", 1.0), + WithArg("auctionValidUntil", otu.currentTime()+10.0), + ) + ot.Run(t, "Should not be able to list an item for auction twice, and will give error message.", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price) + + listTx().AssertFailure(t, "Auction listing for this item is already created.") + }) + + ot.Run(t, "Should be able to sell at auction", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0). + tickClock(400.0). + saleLeaseListed("user5", "finished_completed", price+5.0). + fulfillLeaseMarketAuctionSoft("user6", "user5", 15.0) + }) + + ot.Run(t, "Should be able to cancel listing if the pointer is no longer valid", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0). + tickClock(400.0). + saleLeaseListed("user5", "finished_completed", price+5.0). + moveNameTo("user5", "user6", "user5") + + otu.O.Tx("cancelLeaseMarketAuctionSoft", + WithSigner("user5"), + WithArg("leaseNames", `["user5"]`), + ).AssertSuccess(t). + AssertEvent(t, eventIdentifier, map[string]interface{}{ + "seller": otu.O.Address("user5"), + "buyer": otu.O.Address("user6"), + "amount": 15.0, + "status": "cancel_ghostlisting", + }) + }) + + ot.Run(t, "Should not be able to list with price 0", func(t *testing.T) { + listTx(WithArg("price", 0.0)). + AssertFailure(t, "Auction start price should be greater than 0") + }) + + ot.Run(t, "Should not be able to list with invalid reserve price", func(t *testing.T) { + listTx(WithArg("auctionReservePrice", price-5.0)). + AssertFailure(t, "Auction reserve price should be greater than Auction start price") + }) + + ot.Run(t, "Should not be able to list with invalid time", func(t *testing.T) { + listTx(WithArg("auctionValidUntil", 0.0)). + AssertFailure(t, "Valid until is before current time") + }) + + ot.Run(t, "Should be able to add bid at auction", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0). + increaseAuctionBidLeaseMarketSoft("user6", "user5", 5.0, price+10.0). + tickClock(400.0). + saleLeaseListed("user5", "finished_completed", price+10.0). + fulfillLeaseMarketAuctionSoft("user6", "user5", price+10.0) + }) + + ot.Run(t, "Should not be able to bid expired auction listing", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + tickClock(1000.0) + + bidTx().AssertFailure(t, "This auction listing is already expired") + }) + + ot.Run(t, "Should not be able to bid your own listing", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price) + + bidTx(WithSigner("user5")). + AssertFailure(t, "You cannot bid on your own resource") + }) + + ot.Run(t, "Should be able to cancel an auction", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price) + + name := "user5" + + otu.O.Tx("cancelLeaseMarketAuctionSoft", + WithSigner(name), + WithArg("leaseNames", `["user5"]`), + ). + AssertSuccess(t). + AssertEvent(t, eventIdentifier, map[string]interface{}{ + "seller": otu.O.Address(name), + "amount": 10.0, + "status": "cancel", + }) + }) + + ot.Run(t, "Should not be able to cancel an ended auction", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0). + tickClock(4000.0). + saleLeaseListed("user5", "finished_completed", price+5.0) + + name := "user5" + + otu.O.Tx("cancelLeaseMarketAuctionSoft", + WithSigner(name), + WithArg("leaseNames", `["user5"]`), + ). + AssertFailure(t, "Cannot cancel finished auction, fulfill it instead") + + otu.fulfillLeaseMarketAuctionSoft("user6", "user5", price+5.0) + }) + + ot.Run(t, "Cannot fulfill a not yet ended auction", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price) + + otu.auctionBidLeaseMarketSoft("user6", "user5", price+5.0) + + otu.tickClock(100.0) + + otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithPayloadSigner("dapper"), + WithArg("leaseName", "user5"), + WithArg("amount", price+5.0), + ). + AssertFailure(t, "Auction has not ended yet") + }) + + ot.Run(t, "Should allow seller to cancel auction if it failed to meet reserve price", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+1.0). + tickClock(400.0). + saleLeaseListed("user5", "finished_failed", 11.0) + + buyer := "user6" + name := "user5" + + otu.O.Tx("cancelLeaseMarketAuctionSoft", + WithSigner(name), + WithArg("leaseNames", `["user5"]`), + ). + AssertEvent(t, eventIdentifier, map[string]interface{}{ + "seller": otu.O.Address(name), + "buyer": otu.O.Address(buyer), + "amount": 11.0, + "status": "cancel_reserved_not_met", + }) + }) + + ot.Run(t, "Should be able to bid and increase bid by same user", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+preIncrement). + saleLeaseListed("user5", "active_ongoing", price+preIncrement) + + increaseBidTx(WithArg("amount", 0.1)). + AssertFailure(t, "must be larger then previous bid+bidIncrement") + }) + + ot.Run(t, "Should not be able to list after deprecated", func(t *testing.T) { + otu.alterLeaseMarketOption("deprecate") + + listTx().AssertFailure(t, "Tenant has deprected mutation options on this item") + }) + + ot.Run(t, "Should not be able to bid below listing price", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price) + + bidTx(WithArg("amount", 1.0)). + AssertFailure(t, "You need to bid more then the starting price of 10.00000000") + }) + + // platform 0.15 + // artist 0.05 + // find 0.025 + // tenant nil + ot.Run(t, "Royalties should be sent to correspondence upon fulfill action", func(t *testing.T) { + price = 5.0 + + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0) + + otu.tickClock(500.0) + + otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithPayloadSigner("dapper"), + WithArg("leaseName", "user5"), + WithArg("amount", 10.0), + ). + AssertSuccess(t). + AssertEvent(t, royaltyIdentifier, map[string]interface{}{ + "address": otu.O.Address("find"), + "amount": 0.25, + "royaltyName": "find", + }) + }) + /* + + t.Run("Should be able to ban user, user is only allowed to cancel listing.", func(t *testing.T) { + + otu.listLeaseForSoftAuction("user5", "user5", price). + listLeaseForSoftAuction("user5", "name2", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0). + tickClock(400.0). + leaseProfileBan("user5") + + otu.O.Tx("listLeaseForAuctionSoftDapper", + WithSigner("user5"), + WithArg("leaseName", "name3"), + WithArg("ftAliasOrIdentifier", "FUT"), + WithArg("price", price), + WithArg("auctionReservePrice", price+5.0), + WithArg("auctionDuration", 300.0), + WithArg("auctionExtensionOnLateBid", 60.0), + WithArg("minimumBidIncrement", 1.0), + WithArg("auctionValidUntil", otu.currentTime()+10.0), + ). + AssertFailure(t, "Seller banned by Tenant") + + otu.O.Tx("bidLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithArg("leaseName", "name2"), + WithArg("amount", price), + ). + AssertFailure(t, "Seller banned by Tenant") + + otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithPayloadSigner("dapper"), + WithArg("leaseName", "user5"), + WithArg("amount", price+5.0), + ). + AssertFailure(t, "Seller banned by Tenant") + + otu.O.Tx("cancelLeaseMarketAuctionSoft", + WithSigner("user5"), + WithArg("leaseNames", `["name2"]`), + ). + AssertSuccess(t) + + otu.removeLeaseProfileBan("user5") + + otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithPayloadSigner("dapper"), + WithArg("leaseName", "user5"), + WithArg("amount", price+5.0), + ). + AssertSuccess(t) + + otu.delistAllLeaseForSoftAuction("user5"). + moveNameTo("user6", "user5", "user5") + + }) + + t.Run("Should be able to ban user, user cannot bid NFT.", func(t *testing.T) { + + otu.listLeaseForSoftAuction("user5", "user5", price). + listLeaseForSoftAuction("user5", "name2", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0). + tickClock(400.0). + leaseProfileBan("user6") + + otu.O.Tx("bidLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithArg("leaseName", "name2"), + WithArg("amount", price), + ). + AssertFailure(t, "Buyer banned by Tenant") + + otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithPayloadSigner("dapper"), + WithArg("leaseName", "user5"), + WithArg("amount", price+5.0), + ). + AssertFailure(t, "Buyer banned by Tenant") + + otu.removeLeaseProfileBan("user6") + + otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", + WithSigner("user6"), + WithPayloadSigner("dapper"), + WithArg("leaseName", "user5"), + WithArg("amount", price+5.0), + ). + AssertSuccess(t) + + otu.delistAllLeaseForSoftAuction("user5"). + moveNameTo("user6", "user5", "user5") + + }) + + */ + ot.Run(t, "Should emit previous bidder if outbid", func(t *testing.T) { + otu.listLeaseForSoftAuction("user5", "user5", price). + saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoft("user6", "user5", price+5.0). + saleLeaseListed("user5", "active_ongoing", price+5.0) + + otu.O.Tx("bidLeaseMarketAuctionSoftDapper", + WithSigner("user7"), + WithArg("leaseName", "user5"), + WithArg("amount", 20.0), + ). + AssertSuccess(t). + AssertEvent(t, eventIdentifier, map[string]interface{}{ + "amount": 20.0, + "buyer": otu.O.Address("user7"), + "previousBuyer": otu.O.Address("user6"), + "status": "active_ongoing", + }) + }) + + ot.Run(t, "Should be able to list an NFT for auction and bid it with DUC", func(t *testing.T) { + otu.listLeaseForSoftAuctionDUC("user5", "user5", price) + + otu.saleLeaseListed("user5", "active_listed", price). + auctionBidLeaseMarketSoftDUC("user6", "user5", price+5.0) + + otu.O.Tx("increaseBidLeaseMarketAuctionSoft", + WithSigner("user6"), + WithArg("leaseName", "user5"), + WithArg("amount", 5.0), + ). + AssertSuccess(t) + + otu.tickClock(400.0). + saleLeaseListed("user5", "finished_completed", price+10.0). + fulfillLeaseMarketAuctionSoftDUC("user6", "user5", price+10.0) + }) +} diff --git a/lease_market_auction_soft_test.go b/lease_market_auction_soft_test.go index 6f3c22e7..74a1ea63 100644 --- a/lease_market_auction_soft_test.go +++ b/lease_market_auction_soft_test.go @@ -2,377 +2,20 @@ package test_main import ( "testing" - - . "github.com/bjartek/overflow/v2" ) -func TestLeaseMarketAuctionSoft(t *testing.T) { +func TestLeaseMarketAuctionSoftFlow(t *testing.T) { otu := &OverflowTestUtils{T: t, O: ot.O} price := 10.0 - preIncrement := 5.0 - - eventIdentifier := otu.identifier("FindLeaseMarketAuctionSoft", "EnglishAuction") - royaltyIdentifier := otu.identifier("FindLeaseMarket", "RoyaltyPaid") - - bidTx := otu.O.TxFileNameFN("bidLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithArg("leaseName", "user5"), - WithArg("amount", price), - ) - - increaseBidTx := otu.O.TxFileNameFN("increaseBidLeaseMarketAuctionSoft", - WithSigner("user6"), - WithArg("leaseName", "user5"), - WithArg("amount", preIncrement), - ) - - listTx := otu.O.TxFileNameFN("listLeaseForAuctionSoftDapper", - WithSigner("user5"), - WithArg("leaseName", "user5"), - WithArg("ftAliasOrIdentifier", "FUT"), - WithArg("price", price), - WithArg("auctionReservePrice", price+5.0), - WithArg("auctionDuration", 300.0), - WithArg("auctionExtensionOnLateBid", 60.0), - WithArg("minimumBidIncrement", 1.0), - WithArg("auctionValidUntil", otu.currentTime()+10.0), - ) - ot.Run(t, "Should not be able to list an item for auction twice, and will give error message.", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price) - - listTx().AssertFailure(t, "Auction listing for this item is already created.") - }) ot.Run(t, "Should be able to sell at auction", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0). - tickClock(400.0). - saleLeaseListed("user5", "finished_completed", price+5.0). - fulfillLeaseMarketAuctionSoft("user6", "user5", 15.0) - }) - - ot.Run(t, "Should be able to cancel listing if the pointer is no longer valid", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0). - tickClock(400.0). - saleLeaseListed("user5", "finished_completed", price+5.0). - moveNameTo("user5", "user6", "user5") - - otu.O.Tx("cancelLeaseMarketAuctionSoft", - WithSigner("user5"), - WithArg("leaseNames", `["user5"]`), - ).AssertSuccess(t). - AssertEvent(t, eventIdentifier, map[string]interface{}{ - "seller": otu.O.Address("user5"), - "buyer": otu.O.Address("user6"), - "amount": 15.0, - "status": "cancel_ghostlisting", - }) - }) - - ot.Run(t, "Should not be able to list with price 0", func(t *testing.T) { - listTx(WithArg("price", 0.0)). - AssertFailure(t, "Auction start price should be greater than 0") - }) - - ot.Run(t, "Should not be able to list with invalid reserve price", func(t *testing.T) { - listTx(WithArg("auctionReservePrice", price-5.0)). - AssertFailure(t, "Auction reserve price should be greater than Auction start price") - }) - - ot.Run(t, "Should not be able to list with invalid time", func(t *testing.T) { - listTx(WithArg("auctionValidUntil", 0.0)). - AssertFailure(t, "Valid until is before current time") - }) - - ot.Run(t, "Should be able to add bid at auction", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0). - increaseAuctionBidLeaseMarketSoft("user6", "user5", 5.0, price+10.0). - tickClock(400.0). - saleLeaseListed("user5", "finished_completed", price+10.0). - fulfillLeaseMarketAuctionSoft("user6", "user5", price+10.0) - }) - - ot.Run(t, "Should not be able to bid expired auction listing", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - tickClock(1000.0) - - bidTx().AssertFailure(t, "This auction listing is already expired") - }) - - ot.Run(t, "Should not be able to bid your own listing", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price) - - bidTx(WithSigner("user5")). - AssertFailure(t, "You cannot bid on your own resource") - }) - - ot.Run(t, "Should be able to cancel an auction", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price) - - name := "user5" - - otu.O.Tx("cancelLeaseMarketAuctionSoft", - WithSigner(name), - WithArg("leaseNames", `["user5"]`), - ). - AssertSuccess(t). - AssertEvent(t, eventIdentifier, map[string]interface{}{ - "seller": otu.O.Address(name), - "amount": 10.0, - "status": "cancel", - }) - }) - - ot.Run(t, "Should not be able to cancel an ended auction", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0). - tickClock(4000.0). - saleLeaseListed("user5", "finished_completed", price+5.0) - - name := "user5" - - otu.O.Tx("cancelLeaseMarketAuctionSoft", - WithSigner(name), - WithArg("leaseNames", `["user5"]`), - ). - AssertFailure(t, "Cannot cancel finished auction, fulfill it instead") - - otu.fulfillLeaseMarketAuctionSoft("user6", "user5", price+5.0) - }) - - ot.Run(t, "Cannot fulfill a not yet ended auction", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price) - - otu.auctionBidLeaseMarketSoft("user6", "user5", price+5.0) - - otu.tickClock(100.0) - - otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithPayloadSigner("dapper"), - WithArg("leaseName", "user5"), - WithArg("amount", price+5.0), - ). - AssertFailure(t, "Auction has not ended yet") - }) - ot.Run(t, "Should allow seller to cancel auction if it failed to meet reserve price", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+1.0). + otu.listLeaseForSoftAuctionFlow("user1", "user1", price). + saleLeaseListed("user1", "active_listed", price). + auctionBidLeaseMarketSoftFlow("user2", "user1", price+5.0). tickClock(400.0). - saleLeaseListed("user5", "finished_failed", 11.0) - - buyer := "user6" - name := "user5" - - otu.O.Tx("cancelLeaseMarketAuctionSoft", - WithSigner(name), - WithArg("leaseNames", `["user5"]`), - ). - AssertEvent(t, eventIdentifier, map[string]interface{}{ - "seller": otu.O.Address(name), - "buyer": otu.O.Address(buyer), - "amount": 11.0, - "status": "cancel_reserved_not_met", - }) - }) - - ot.Run(t, "Should be able to bid and increase bid by same user", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+preIncrement). - saleLeaseListed("user5", "active_ongoing", price+preIncrement) - - increaseBidTx(WithArg("amount", 0.1)). - AssertFailure(t, "must be larger then previous bid+bidIncrement") - }) - - ot.Run(t, "Should not be able to list after deprecated", func(t *testing.T) { - otu.alterLeaseMarketOption("deprecate") - - listTx().AssertFailure(t, "Tenant has deprected mutation options on this item") - }) - - ot.Run(t, "Should not be able to bid below listing price", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price) - - bidTx(WithArg("amount", 1.0)). - AssertFailure(t, "You need to bid more then the starting price of 10.00000000") - }) - - // platform 0.15 - // artist 0.05 - // find 0.025 - // tenant nil - ot.Run(t, "Royalties should be sent to correspondence upon fulfill action", func(t *testing.T) { - price = 5.0 - - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0) - - otu.tickClock(500.0) - - otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithPayloadSigner("dapper"), - WithArg("leaseName", "user5"), - WithArg("amount", 10.0), - ). - AssertSuccess(t). - AssertEvent(t, royaltyIdentifier, map[string]interface{}{ - "address": otu.O.Address("find"), - "amount": 0.25, - "royaltyName": "find", - }) - }) - /* - - t.Run("Should be able to ban user, user is only allowed to cancel listing.", func(t *testing.T) { - - otu.listLeaseForSoftAuction("user5", "user5", price). - listLeaseForSoftAuction("user5", "name2", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0). - tickClock(400.0). - leaseProfileBan("user5") - - otu.O.Tx("listLeaseForAuctionSoftDapper", - WithSigner("user5"), - WithArg("leaseName", "name3"), - WithArg("ftAliasOrIdentifier", "FUT"), - WithArg("price", price), - WithArg("auctionReservePrice", price+5.0), - WithArg("auctionDuration", 300.0), - WithArg("auctionExtensionOnLateBid", 60.0), - WithArg("minimumBidIncrement", 1.0), - WithArg("auctionValidUntil", otu.currentTime()+10.0), - ). - AssertFailure(t, "Seller banned by Tenant") - - otu.O.Tx("bidLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithArg("leaseName", "name2"), - WithArg("amount", price), - ). - AssertFailure(t, "Seller banned by Tenant") - - otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithPayloadSigner("dapper"), - WithArg("leaseName", "user5"), - WithArg("amount", price+5.0), - ). - AssertFailure(t, "Seller banned by Tenant") - - otu.O.Tx("cancelLeaseMarketAuctionSoft", - WithSigner("user5"), - WithArg("leaseNames", `["name2"]`), - ). - AssertSuccess(t) - - otu.removeLeaseProfileBan("user5") - - otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithPayloadSigner("dapper"), - WithArg("leaseName", "user5"), - WithArg("amount", price+5.0), - ). - AssertSuccess(t) - - otu.delistAllLeaseForSoftAuction("user5"). - moveNameTo("user6", "user5", "user5") - - }) - - t.Run("Should be able to ban user, user cannot bid NFT.", func(t *testing.T) { - - otu.listLeaseForSoftAuction("user5", "user5", price). - listLeaseForSoftAuction("user5", "name2", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0). - tickClock(400.0). - leaseProfileBan("user6") - - otu.O.Tx("bidLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithArg("leaseName", "name2"), - WithArg("amount", price), - ). - AssertFailure(t, "Buyer banned by Tenant") - - otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithPayloadSigner("dapper"), - WithArg("leaseName", "user5"), - WithArg("amount", price+5.0), - ). - AssertFailure(t, "Buyer banned by Tenant") - - otu.removeLeaseProfileBan("user6") - - otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", - WithSigner("user6"), - WithPayloadSigner("dapper"), - WithArg("leaseName", "user5"), - WithArg("amount", price+5.0), - ). - AssertSuccess(t) - - otu.delistAllLeaseForSoftAuction("user5"). - moveNameTo("user6", "user5", "user5") - - }) - - */ - ot.Run(t, "Should emit previous bidder if outbid", func(t *testing.T) { - otu.listLeaseForSoftAuction("user5", "user5", price). - saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoft("user6", "user5", price+5.0). - saleLeaseListed("user5", "active_ongoing", price+5.0) - - otu.O.Tx("bidLeaseMarketAuctionSoftDapper", - WithSigner("user7"), - WithArg("leaseName", "user5"), - WithArg("amount", 20.0), - ). - AssertSuccess(t). - AssertEvent(t, eventIdentifier, map[string]interface{}{ - "amount": 20.0, - "buyer": otu.O.Address("user7"), - "previousBuyer": otu.O.Address("user6"), - "status": "active_ongoing", - }) - }) - - ot.Run(t, "Should be able to list an NFT for auction and bid it with DUC", func(t *testing.T) { - otu.listLeaseForSoftAuctionDUC("user5", "user5", price) - - otu.saleLeaseListed("user5", "active_listed", price). - auctionBidLeaseMarketSoftDUC("user6", "user5", price+5.0) - - otu.O.Tx("increaseBidLeaseMarketAuctionSoft", - WithSigner("user6"), - WithArg("leaseName", "user5"), - WithArg("amount", 5.0), - ). - AssertSuccess(t) - - otu.tickClock(400.0). - saleLeaseListed("user5", "finished_completed", price+10.0). - fulfillLeaseMarketAuctionSoftDUC("user6", "user5", price+10.0) + saleLeaseListed("user1", "finished_completed", price+5.0). + fulfillLeaseMarketAuctionSoftFlow("user2", "user1", 15.0) }) } diff --git a/lease_market_direct_offer_soft_flow_test.go b/lease_market_direct_offer_soft_flow_test.go new file mode 100644 index 00000000..12d323f1 --- /dev/null +++ b/lease_market_direct_offer_soft_flow_test.go @@ -0,0 +1,20 @@ +package test_main + +import ( + "testing" +) + +func TestLeaseMarketDirectOfferSoftFlow(t *testing.T) { + otu := &OverflowTestUtils{T: t, O: ot.O} + + price := 10.0 + + + ot.Run(t, "Should be able to add direct offer and then sell", func(t *testing.T) { + otu.directOfferLeaseMarketSoftFlow("user2", "user1", price). + saleLeaseListed("user1", "active_ongoing", price). + acceptLeaseDirectOfferMarketSoftFlow("user2", "user1", "user1", price). + saleLeaseListed("user1", "active_finished", price). + fulfillLeaseMarketDirectOfferSoftFlow("user2", "user1", price) + }) +} diff --git a/lease_market_sale_flow_test.go b/lease_market_sale_flow_test.go new file mode 100644 index 00000000..b7316d15 --- /dev/null +++ b/lease_market_sale_flow_test.go @@ -0,0 +1,25 @@ +package test_main + +import ( + "testing" + + //. "github.com/bjartek/overflow/v2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLeaseMarketSaleFlow(t *testing.T) { + otu := &OverflowTestUtils{T: t, O: ot.O} + price := 10.0 + + ot.Run(t, "Should be able to list a lease for sale and buy it", func(t *testing.T) { + otu.listLeaseForSale("user1", "user1", price) + + itemsForSale := otu.getLeasesForSale("user1") + require.Equal(t, 1, len(itemsForSale)) + assert.Equal(t, "active_listed", itemsForSale[0].SaleType) + + otu.buyLeaseForMarketSale("user2", "user1", "user1", price) + }) + +} diff --git a/lease_market_sale_test.go b/lease_market_sale_test.go index f7322d64..a19acbdf 100644 --- a/lease_market_sale_test.go +++ b/lease_market_sale_test.go @@ -196,4 +196,23 @@ func TestLeaseMarketSale(t *testing.T) { ). AssertFailure(t, "Seller banned by Tenant") }) + + + ot.Run(t, "Should be able to list two leases for sale", func(t *testing.T) { + + otu.O.Tx("devRegisterDapper", + WithSigner("user5"), + WithPayloadSigner("dapper"), + WithArg("merchAccount", "dapper"), + WithArg("name", "name5"), + WithArg("amount", 5.0), + ).AssertSuccess(otu.T) + + otu.listLeaseForSaleDUC("user5", "user5", price) + otu.listLeaseForSaleDUC("user5", "name5", price) + + itemsForSale := otu.getLeasesForSale("user5") + require.Equal(t, 2 , len(itemsForSale)) + + }) } diff --git a/lib/find.json b/lib/find.json index 9b6e1554..430dc88b 100644 --- a/lib/find.json +++ b/lib/find.json @@ -42,7 +42,7 @@ "user" ] }, - "code": "import FIND from 0xf3fcd2c1a78f5eee\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport Clock from 0xf3fcd2c1a78f5eee\n\naccess(all) struct FINDReport{\n\n access(all) let leases: [FIND.LeaseInformation]\n access(all) let leasesBids: [FIND.BidInfo]\n access(all) let itemsForSale: {String : FindMarket.SaleItemCollectionReport}\n access(all) let marketBids: {String : FindMarket.BidItemCollectionReport}\n\n init(\n bids: [FIND.BidInfo],\n leases : [FIND.LeaseInformation],\n leasesBids: [FIND.BidInfo],\n itemsForSale: {String : FindMarket.SaleItemCollectionReport},\n marketBids: {String : FindMarket.BidItemCollectionReport},\n ) {\n\n self.leases=leases\n self.leasesBids=leasesBids\n self.itemsForSale=itemsForSale\n self.marketBids=marketBids\n }\n}\n\n\naccess(all) fun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n let bidCap=account.capabilities.borrow\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n let leaseCap = account.capabilities.borrow\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n\n let leases = leaseCap?.getLeaseInformation() ?? []\n let oldLeaseBid = bidCap?.getBids() ?? []\n\n let find= FindMarket.getFindTenantAddress()\n var items : {String : FindMarket.SaleItemCollectionReport} = FindMarket.getSaleItemReport(tenant:find, address: address, getNFTInfo:true)\n var marketBids : {String : FindMarket.BidItemCollectionReport} = FindMarket.getBidsReport(tenant:find, address: address, getNFTInfo:true)\n\n return FINDReport(\n bids: oldLeaseBid,\n leases: leases,\n leasesBids: oldLeaseBid,\n itemsForSale: items,\n marketBids: marketBids,\n )\n}" + "code": "import FIND from 0xf3fcd2c1a78f5eee\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport Clock from 0xf3fcd2c1a78f5eee\n\naccess(all) struct FINDReport{\n\n access(all) let leases: [FIND.LeaseInformation]\n access(all) let leasesBids: [FIND.BidInfo]\n access(all) let itemsForSale: {String : FindMarket.SaleItemCollectionReport}\n access(all) let marketBids: {String : FindMarket.BidItemCollectionReport}\n\n init(\n bids: [FIND.BidInfo],\n leases : [FIND.LeaseInformation],\n leasesBids: [FIND.BidInfo],\n itemsForSale: {String : FindMarket.SaleItemCollectionReport},\n marketBids: {String : FindMarket.BidItemCollectionReport},\n ) {\n\n self.leases=leases\n self.leasesBids=leasesBids\n self.itemsForSale=itemsForSale\n self.marketBids=marketBids\n }\n}\n\n\naccess(all) fun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n let leaseCap = account.capabilities.borrow\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n let leases = leaseCap?.getLeaseInformation() ?? []\n let find= FindMarket.getFindTenantAddress()\n var items : {String : FindMarket.SaleItemCollectionReport} = FindMarket.getSaleItemReport(tenant:find, address: address, getNFTInfo:true)\n var marketBids : {String : FindMarket.BidItemCollectionReport} = FindMarket.getBidsReport(tenant:find, address: address, getNFTInfo:true)\n\n return FINDReport(\n bids: [],\n leases: leases,\n leasesBids: [],\n itemsForSale: items,\n marketBids: marketBids,\n )\n}" }, "getFindNameMarket": { "spec": { @@ -64,7 +64,7 @@ "user" ] }, - "code": "import FIND from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindRelatedAccounts from 0xf3fcd2c1a78f5eee\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport TokenForwarding from 0xf8d6e0586b0a20c7\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FindUtils from 0xf3fcd2c1a78f5eee\nimport Clock from 0xf3fcd2c1a78f5eee\nimport LostAndFound from 0xf8d6e0586b0a20c7\n\naccess(all) \nstruct FINDReport{\n access(all) let isDapper: Bool\n access(all) let profile:Profile.UserReport?\n access(all) let privateMode: Bool\n access(all) let activatedAccount: Bool\n access(all) let hasLostAndFoundItem: Bool\n access(all) let accounts : [AccountInformation]?\n //not sure\n access(all) let readyForWearables : Bool?\n\n init(profile: Profile.UserReport?,\n privateMode: Bool,\n activatedAccount: Bool,\n isDapper: Bool,\n hasLostAndFoundItem: Bool,\n accounts: [AccountInformation]?,\n readyForWearables: Bool?\n) {\n\n self.hasLostAndFoundItem=hasLostAndFoundItem\n self.profile=profile\n self.privateMode=privateMode\n self.activatedAccount=activatedAccount\n self.isDapper=isDapper\n self.accounts=accounts\n self.readyForWearables=readyForWearables\n}\n}\n\naccess(all) struct AccountInformation {\n access(all) let name: String\n access(all) let address: String\n access(all) let network: String\n access(all) let trusted: Bool\n access(all) let node: String\n\n init(name: String, address: String, network: String, trusted: Bool, node: String) {\n self.name = name\n self.address = address\n self.network = network\n self.trusted = trusted\n self.node = node\n }\n}\n\n\naccess(all) \nfun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n //why not auth account here?\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n var isDapper=false\n if let receiver =account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver) {\n isDapper=receiver.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n if let duc = account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver){\n isDapper = duc.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n isDapper = false\n }\n }\n\n let profile=account.capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n var profileReport = profile?.asReport()\n if profileReport != nil \u0026\u0026 profileReport!.findName != FIND.reverseLookup(address) {\n profileReport = Profile.UserReport(\n findName: \"\",\n address: profileReport!.address,\n name: profileReport!.name,\n gender: profileReport!.gender,\n description: profileReport!.description,\n tags: profileReport!.tags,\n avatar: profileReport!.avatar,\n links: profileReport!.links,\n wallets: profileReport!.wallets,\n following: profileReport!.following,\n followers: profileReport!.followers,\n allowStoringFollowers: profileReport!.allowStoringFollowers,\n createdAt: profileReport!.createdAt\n )\n }\n\n let discordID = \"\"//EmeraldIdentity.getDiscordFromAccount(account: address) ?? \"\"\n\n let emeraldIDAccounts : {String : Address} = {}\n //emeraldIDAccounts[\"blocto\"] = EmeraldIdentity.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"lilico\"] = EmeraldIdentityLilico.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"dapper\"] = EmeraldIdentityDapper.getAccountFromDiscord(discordID: discordID)\n\n let accounts : [AccountInformation] = []\n for wallet in [\"blocto\", \"lilico\", \"dapper\"] {\n if let w = emeraldIDAccounts[wallet] {\n if w == address {\n continue\n }\n\n accounts.append(\n AccountInformation(\n name: wallet,\n address: w.toString(),\n network: \"Flow\",\n trusted: true,\n node: \"EmeraldID\")\n )\n }\n }\n\n if let allAcctsCap = FindRelatedAccounts.getCapability(address) {\n let allAcctsRef = allAcctsCap.borrow()!\n let allAccts = allAcctsRef.getAllRelatedAccountInfo()\n for acct in allAccts.values {\n // We only verify flow accounts that are mutually linked\n var trusted = false\n if acct.address != nil {\n if acct.address! == address {\n continue\n }\n trusted = allAcctsRef.linked(name: acct.name, network: acct.network, address: acct.address!)\n }\n accounts.append(AccountInformation(\n name: acct.name,\n address: acct.stringAddress,\n network: acct.network,\n trusted: trusted,\n node: \"FindRelatedAccounts\")\n )\n }\n }\n\n var readyForWearables = false\n var hasLostAndFoundItem : Bool = false\n\n for t in LostAndFound.getRedeemableTypes(address) {\n if t.isSubtype(of: Type\u003c@{NonFungibleToken.NFT}\u003e()) {\n hasLostAndFoundItem = true\n break\n }\n }\n\n return FINDReport(\n profile: profileReport,\n privateMode: profile?.isPrivateModeEnabled() ?? false,\n activatedAccount: true,\n isDapper:isDapper,\n hasLostAndFoundItem: hasLostAndFoundItem,\n accounts: accounts,\n readyForWearables: readyForWearables,\n )\n }" + "code": "import FIND from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindRelatedAccounts from 0xf3fcd2c1a78f5eee\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport TokenForwarding from 0xf8d6e0586b0a20c7\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FindUtils from 0xf3fcd2c1a78f5eee\nimport Clock from 0xf3fcd2c1a78f5eee\nimport LostAndFound from 0xf8d6e0586b0a20c7\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\n\naccess(all) struct FINDReport{\n access(all) let isDapper: Bool\n access(all) let profile:Profile.UserReport?\n access(all) let privateMode: Bool\n access(all) let activatedAccount: Bool\n access(all) let hasLostAndFoundItem: Bool\n access(all) let isReadyForNameOffer: Bool\n access(all) let accounts : [AccountInformation]?\n //not sure\n access(all) let readyForWearables : Bool?\n\n init(profile: Profile.UserReport?,\n privateMode: Bool,\n activatedAccount: Bool,\n isDapper: Bool,\n hasLostAndFoundItem: Bool,\n accounts: [AccountInformation]?,\n readyForWearables: Bool?,\n isReadyForNameOffer: Bool) {\n\n self.hasLostAndFoundItem=hasLostAndFoundItem\n self.profile=profile\n self.privateMode=privateMode\n self.activatedAccount=activatedAccount\n self.isDapper=isDapper\n self.accounts=accounts\n self.readyForWearables=readyForWearables\n self.isReadyForNameOffer=isReadyForNameOffer\n }\n}\n\naccess(all) struct AccountInformation {\n access(all) let name: String\n access(all) let address: String\n access(all) let network: String\n access(all) let trusted: Bool\n access(all) let node: String\n\n init(name: String, address: String, network: String, trusted: Bool, node: String) {\n self.name = name\n self.address = address\n self.network = network\n self.trusted = trusted\n self.node = node\n }\n}\n\n\naccess(all) \nfun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n //why not auth account here?\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n var isDapper=false\n if let receiver =account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver) {\n isDapper=receiver.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n if let duc = account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver){\n isDapper = duc.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n isDapper = false\n }\n }\n\n let profile=account.capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n var profileReport = profile?.asReport()\n if profileReport != nil \u0026\u0026 profileReport!.findName != FIND.reverseLookup(address) {\n profileReport = Profile.UserReport(\n findName: \"\",\n address: profileReport!.address,\n name: profileReport!.name,\n gender: profileReport!.gender,\n description: profileReport!.description,\n tags: profileReport!.tags,\n avatar: profileReport!.avatar,\n links: profileReport!.links,\n wallets: profileReport!.wallets,\n following: profileReport!.following,\n followers: profileReport!.followers,\n allowStoringFollowers: profileReport!.allowStoringFollowers,\n createdAt: profileReport!.createdAt\n )\n }\n\n let discordID = \"\"//EmeraldIdentity.getDiscordFromAccount(account: address) ?? \"\"\n\n let emeraldIDAccounts : {String : Address} = {}\n //emeraldIDAccounts[\"blocto\"] = EmeraldIdentity.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"lilico\"] = EmeraldIdentityLilico.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"dapper\"] = EmeraldIdentityDapper.getAccountFromDiscord(discordID: discordID)\n\n let accounts : [AccountInformation] = []\n for wallet in [\"blocto\", \"lilico\", \"dapper\"] {\n if let w = emeraldIDAccounts[wallet] {\n if w == address {\n continue\n }\n\n accounts.append(\n AccountInformation(\n name: wallet,\n address: w.toString(),\n network: \"Flow\",\n trusted: true,\n node: \"EmeraldID\")\n )\n }\n }\n\n if let allAcctsCap = FindRelatedAccounts.getCapability(address) {\n let allAcctsRef = allAcctsCap.borrow()!\n let allAccts = allAcctsRef.getAllRelatedAccountInfo()\n for acct in allAccts.values {\n // We only verify flow accounts that are mutually linked\n var trusted = false\n if acct.address != nil {\n if acct.address! == address {\n continue\n }\n trusted = allAcctsRef.linked(name: acct.name, network: acct.network, address: acct.address!)\n }\n accounts.append(AccountInformation(\n name: acct.name,\n address: acct.stringAddress,\n network: acct.network,\n trusted: trusted,\n node: \"FindRelatedAccounts\")\n )\n }\n }\n\n var readyForWearables = false\n var hasLostAndFoundItem : Bool = false\n\n for t in LostAndFound.getRedeemableTypes(address) {\n if t.isSubtype(of: Type\u003c@{NonFungibleToken.NFT}\u003e()) {\n hasLostAndFoundItem = true\n break\n }\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n let readyForLeaseOffer =leaseDOSSaleItemCap.check()\n\n return FINDReport(\n profile: profileReport,\n privateMode: profile?.isPrivateModeEnabled() ?? false,\n activatedAccount: true,\n isDapper:isDapper,\n hasLostAndFoundItem: hasLostAndFoundItem,\n accounts: accounts,\n readyForWearables: readyForWearables,\n isReadyForNameOffer: readyForLeaseOffer\n )\n }" }, "getFindThoughts": { "spec": { @@ -79,6 +79,13 @@ }, "code": "import FindThoughts from 0xf3fcd2c1a78f5eee\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\n\naccess(all) fun main(addresses: [Address], ids: [UInt64]) : [Thought] {\n let thoughts : [Thought] = [] \n\n for i, address in addresses {\n let account = getAccount(address) \n if let ref = account.capabilities.borrow\u003c\u0026{FindThoughts.CollectionPublic}\u003e(FindThoughts.CollectionPublicPath) {\n let t = ref.borrowThoughtPublic(ids[i]) \n thoughts.append(getThought(t, withQuote: true))\n }\n\n }\n return thoughts\n}\n\naccess(all) struct User {\n access(all) var name: String?\n access(all) let address: Address \n access(all) let findName: String? \n access(all) var avatar: String? \n access(all) let reaction: String\n\n init(address: Address, reaction: String){\n self.name = nil\n self.findName = FIND.reverseLookup(address)\n self.avatar = nil\n self.reaction = reaction\n self.address = address \n if let p = getAccount(address).capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath) {\n self.name = p.getName()\n self.avatar = p.getAvatar()\n }\n } \n}\n\naccess(all) struct Thought {\n access(all) let id: UInt64 \n access(all) let creator: Address \n access(all) let creatorName: String? \n access(all) var creatorProfileName: String? \n access(all) var creatorAvatar: String? \n access(all) var header: String?\n access(all) var body: String?\n access(all) let created: UFix64? \n access(all) var lastUpdated: UFix64?\n access(all) let medias: {String : String}\n access(all) let nft: [FindMarket.NFTInfo]\n access(all) var tags: [String]\n access(all) var reacted: {String : [User]}\n access(all) var reactions: {String : Int}\n access(all) var reactedUsers: {String : [String]}\n access(all) var quotedThought: Thought?\n access(all) let hidden: Bool?\n\n init(id: UInt64 , creator: Address , creatorName: String? , creatorProfileName: String? , creatorAvatar: String? , header: String? , body: String? , created: UFix64? , lastUpdated: UFix64?, medias: {String : String}, nft: [FindMarket.NFTInfo], tags: [String], reacted: {String : [User]}, reactions: {String : Int}, reactedUsers: {String : [String]}, quotedThought: Thought?, hidden: Bool?) {\n self.id = id\n self.creator = creator\n self.creatorName = creatorName\n self.creatorProfileName = creatorProfileName\n self.creatorAvatar = creatorAvatar\n self.header = header\n self.body = body\n self.created = created\n self.lastUpdated = lastUpdated\n self.medias = medias\n self.nft = nft\n self.tags = tags\n self.reacted = reacted\n self.reactions = reactions\n self.reactedUsers = reactedUsers\n self.quotedThought = quotedThought\n self.hidden = hidden\n }\n}\n\naccess(all) fun getThought(_ t: \u0026{FindThoughts.ThoughtPublic}, withQuote: Bool) : Thought {\n\n var creatorProfileName : String? = nil\n var creatorAvatar : String? = nil \n if let profile = getAccount(t.creator).capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath) {\n creatorProfileName = profile.getName()\n creatorAvatar = profile.getAvatar()\n }\n\n let medias : {String : String} = {}\n for m in t.medias {\n medias[m.file.uri()] = m.mediaType\n }\n\n let nft : [FindMarket.NFTInfo] = [] \n let nftLength = t.getNFTS().length\n for n in t.nft {\n let vr = n.getViewResolver() \n nft.append(FindMarket.NFTInfo(vr, id: n.id, detail: true))\n }\n\n let reacted : {String : [User]} = {}\n let reactedUsers : {String :[String]} = {}\n for user in t.reacted.keys {\n let reaction = t.reacted[user]!\n let allReacted = reacted[reaction] ?? []\n let u = User(address: user, reaction: reaction)\n\n allReacted.append(u)\n reacted[reaction] = allReacted\n\n let preReactedUser = reactedUsers[reaction] ?? []\n preReactedUser.append(u.name ?? u.address.toString())\n reactedUsers[reaction] = preReactedUser\n }\n\n var quotedThought : Thought? = nil \n if withQuote {\n if let p = t.getQuotedThought() {\n if let ref = p.borrowThoughtPublic() {\n quotedThought = getThought(ref, withQuote: false)\n } else {\n let creator = p.owner()\n var qCreatorProfileName : String? = nil\n var qCreatorAvatar : String? = nil \n if let qProfile = getAccount(creator).capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath) {\n qCreatorProfileName = qProfile.getName()\n qCreatorAvatar = qProfile.getAvatar()\n }\n\n quotedThought = Thought(\n id: p.id , \n creator: creator , \n creatorName: FIND.reverseLookup(creator) , \n creatorProfileName: qCreatorProfileName , \n creatorAvatar: qCreatorAvatar, \n header: nil, \n body: nil , \n created: nil, \n lastUpdated: nil, \n medias: {}, \n nft: [], \n tags: [], \n reacted: {}, \n reactions: {}, \n reactedUsers: {},\n quotedThought: nil, \n hidden: nil\n )\n }\n }\n }\n\n return Thought(\n id: t.id , \n creator: t.creator , \n creatorName: FIND.reverseLookup(t.creator) , \n creatorProfileName: creatorProfileName , \n creatorAvatar: creatorAvatar, \n header: t.header , \n body: t.body , \n created: t.created, \n lastUpdated: t.lastUpdated, \n medias: medias, \n nft: nft, \n tags: t.getTags(), \n reacted: reacted, \n reactions: t.getReactions(), \n reactedUsers: reactedUsers,\n quotedThought: quotedThought,\n hidden: t.getHide()\n )\n\n}" }, + "getFlowToUSD": { + "spec": { + "parameters": {}, + "order": [] + }, + "code": "import PublicPriceOracle from 0xf8d6e0586b0a20c7\n\naccess(all) fun main():UFix64? {\n\n let feeds = PublicPriceOracle.getAllSupportedOracles()\n for address in feeds.keys {\n\n let name= feeds[address]\n if name==\"FLOW/USD\" {\n return PublicPriceOracle.getLatestPrice(oracleAddr: address)\n }\n\n }\n return nil\n}" + }, "getLostAndFoundNFTs": { "spec": { "parameters": { @@ -318,6 +325,13 @@ }, "code": "import FindThoughts from 0xf3fcd2c1a78f5eee\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\n\naccess(all) fun main(address: Address) : [Thought] {\n let thoughts : [Thought] = [] \n\n let account = getAccount(address) \n if let ref = account.capabilities.borrow\u003c\u0026{FindThoughts.CollectionPublic}\u003e(FindThoughts.CollectionPublicPath) {\n let a = ref as! \u0026FindThoughts.Collection\n for id in a.getIDs() {\n let t = ref.borrowThoughtPublic(id) \n thoughts.append(getThought(t, withQuote: true))\n }\n\n }\n return thoughts\n}\n\naccess(all) struct User {\n access(all) var name: String?\n access(all) let address: Address \n access(all) let findName: String? \n access(all) var avatar: String? \n access(all) let reaction: String\n\n init(address: Address, reaction: String){\n self.name = nil\n self.findName = FIND.reverseLookup(address)\n self.avatar = nil\n self.reaction = reaction\n self.address = address \n if let p = getAccount(address).capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath) {\n self.name = p.getName()\n self.avatar = p.getAvatar()\n }\n }\n}\n\naccess(all) struct Thought {\n access(all) let id: UInt64 \n access(all) let creator: Address \n access(all) let creatorName: String? \n access(all) var creatorProfileName: String? \n access(all) var creatorAvatar: String? \n access(all) var header: String?\n access(all) var body: String?\n access(all) let created: UFix64? \n access(all) var lastUpdated: UFix64?\n access(all) let medias: {String : String}\n access(all) let nft: [FindMarket.NFTInfo]\n access(all) var tags: [String]\n access(all) var reacted: {String : [User]}\n access(all) var reactions: {String : Int}\n access(all) var reactedUsers: {String : [String]}\n access(all) var quotedThought: Thought?\n access(all) var hidden: Bool?\n\n init(id: UInt64 , creator: Address , creatorName: String? , creatorProfileName: String? , creatorAvatar: String? , header: String? , body: String? , created: UFix64? , lastUpdated: UFix64?, medias: {String : String}, nft: [FindMarket.NFTInfo], tags: [String], reacted: {String : [User]}, reactions: {String : Int}, reactedUsers: {String : [String]}, quotedThought: Thought?, hidden: Bool?) {\n self.id = id\n self.creator = creator\n self.creatorName = creatorName\n self.creatorProfileName = creatorProfileName\n self.creatorAvatar = creatorAvatar\n self.header = header\n self.body = body\n self.created = created\n self.lastUpdated = lastUpdated\n self.medias = medias\n self.nft = nft\n self.tags = tags\n self.reacted = reacted\n self.reactions = reactions\n self.reactedUsers = reactedUsers\n self.quotedThought = quotedThought\n self.hidden = hidden\n }\n}\n\naccess(all) fun getThought(_ t: \u0026{FindThoughts.ThoughtPublic}, withQuote: Bool) : Thought {\n\n var creatorProfileName : String? = nil\n var creatorAvatar : String? = nil \n if let profile = getAccount(t.creator).capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath) {\n creatorProfileName = profile.getName()\n creatorAvatar = profile.getAvatar()\n }\n\n let medias : {String : String} = {}\n for m in t.medias {\n medias[m.file.uri()] = m.mediaType\n }\n\n let nft : [FindMarket.NFTInfo] = [] \n let nftLength = t.getNFTS().length\n for n in t.nft {\n let vr = n.getViewResolver() \n nft.append(FindMarket.NFTInfo(vr, id: n.id, detail: true))\n }\n\n let reacted : {String : [User]} = {}\n let reactedUsers : {String :[String]} = {}\n for user in t.reacted.keys {\n let reaction = t.reacted[user]!\n let allReacted = reacted[reaction] ?? []\n let u = User(address: user, reaction: reaction)\n\n allReacted.append(u)\n reacted[reaction] = allReacted\n\n let preReactedUser = reactedUsers[reaction] ?? []\n preReactedUser.append(u.name ?? u.address.toString())\n reactedUsers[reaction] = preReactedUser\n }\n\n var quotedThought : Thought? = nil \n if withQuote {\n if let p = t.getQuotedThought() {\n if let ref = p.borrowThoughtPublic() {\n quotedThought = getThought(ref, withQuote: false)\n } else {\n let creator = p.owner()\n var qCreatorProfileName : String? = nil\n var qCreatorAvatar : String? = nil \n if let qProfile = getAccount(creator).capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath) {\n qCreatorProfileName = qProfile.getName()\n qCreatorAvatar = qProfile.getAvatar()\n }\n\n quotedThought = Thought(\n id: p.id , \n creator: creator , \n creatorName: FIND.reverseLookup(creator) , \n creatorProfileName: qCreatorProfileName , \n creatorAvatar: qCreatorAvatar, \n header: nil, \n body: nil , \n created: nil, \n lastUpdated: nil, \n medias: {}, \n nft: [], \n tags: [], \n reacted: {}, \n reactions: {}, \n reactedUsers: {},\n quotedThought: nil, \n hidden: nil\n )\n }\n }\n }\n\n return Thought(\n id: t.id , \n creator: t.creator , \n creatorName: FIND.reverseLookup(t.creator) , \n creatorProfileName: creatorProfileName , \n creatorAvatar: creatorAvatar, \n header: t.header , \n body: t.body , \n created: t.created, \n lastUpdated: t.lastUpdated, \n medias: medias, \n nft: nft, \n tags: t.getTags(), \n reacted: reacted, \n reactions: t.getReactions(), \n reactedUsers: reactedUsers,\n quotedThought: quotedThought,\n hidden: t.getHide()\n )\n\n}" }, + "getPriceFeeds": { + "spec": { + "parameters": {}, + "order": [] + }, + "code": "import PublicPriceOracle from 0xf8d6e0586b0a20c7 \n\n// oracleAddress =\u003e oracleTag\naccess(all) fun main(): {Address: String} {\n return PublicPriceOracle.getAllSupportedOracles()\n}" + }, "getProfile": { "spec": { "parameters": { @@ -486,7 +500,7 @@ "leaseName" ] }, - "code": "import FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String) {\n\n let market : \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n let marketOption = FindMarket.getMarketOptionFromType(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n let item = FindLeaseMarket.assertOperationValid(tenant: marketplace, name: leaseName, marketOption: marketOption)\n let ref = account.capabilities.storage.get\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath) ?? panic(\"Cannot borrow reference to find lease collection. Account : \".concat(account.address.toString()))\n self.pointer= FindLeaseMarket.AuthLeasePointer(ref: ref, name: leaseName)\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n}" + "code": "import FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n}" }, "acceptLeaseDirectOfferSoftDapper": { "spec": { @@ -497,7 +511,7 @@ "leaseName" ] }, - "code": "import FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FIND from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n\n}" + "code": "import FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n\n}" }, "acceptMultipleDirectOfferSoft": { "spec": { @@ -616,7 +630,7 @@ "validUntil" ] }, - "code": "import Profile from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, validUntil: UFix64?) {\n\n let bidsReference: \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection?\n let ftVaultType: Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n\n let resolveAddress = FIND.resolve(leaseName)\n if resolveAddress == nil {panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))}\n let address = resolveAddress!\n\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n self.ftVaultType = ft.type\n\n let walletReference = account.storage.borrow\u003c\u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n assert(walletReference.balance \u003e amount , message: \"Bidder has to have enough balance in wallet\")\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)!\n let leaseDOSBidType= Type\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e()\n let leaseDOSBidPublicPath=leaseTenant.getPublicPath(leaseDOSBidType)\n let leaseDOSBidStoragePath= leaseTenant.getStoragePath(leaseDOSBidType)\n let leaseDOSBidCap= account.getCapability\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath)\n if !leaseDOSBidCap.check() {\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptyMarketBidCollection(receiver:receiverCap, tenantCapability:leaseTenantCapability), to: leaseDOSBidStoragePath)\n account.link\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath, target: leaseDOSBidStoragePath)\n }\n\n self.bidsReference= account.storage.borrow\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(from: leaseDOSBidStoragePath)\n\n }\n\n pre {\n self.bidsReference != nil : \"This account does not have a bid collection\"\n }\n\n execute {\n self.bidsReference!.bid(name:leaseName, amount: amount, vaultType: self.ftVaultType, validUntil: validUntil, saleItemExtraField: {}, bidExtraField: {})\n }\n}" + "code": "import Profile from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, validUntil: UFix64?) {\n\n let bidsReference: auth(FindLeaseMarketDirectOfferSoft.Buyer) \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection?\n let ftVaultType: Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n\n let resolveAddress = FIND.resolve(leaseName)\n if resolveAddress == nil {panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))}\n let address = resolveAddress!\n\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n self.ftVaultType = ft.type\n\n let walletReference = account.storage.borrow\u003c\u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n assert(walletReference.balance \u003e amount , message: \"Bidder has to have enough balance in wallet\")\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let leaseDOSBidType= Type\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e()\n let leaseDOSBidPublicPath=leaseTenant.getPublicPath(leaseDOSBidType)\n let leaseDOSBidStoragePath= leaseTenant.getStoragePath(leaseDOSBidType)\n let leaseDOSBidCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath)\n if !leaseDOSBidCap.check() {\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptyMarketBidCollection(receiver:receiverCap, tenantCapability:leaseTenantCapability), to: leaseDOSBidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidStoragePath)\n account.capabilities.publish(cap, at: leaseDOSBidPublicPath)\n }\n\n self.bidsReference= account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Buyer) \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(from: leaseDOSBidStoragePath)\n\n }\n\n pre {\n self.bidsReference != nil : \"This account does not have a bid collection\"\n }\n\n execute {\n self.bidsReference!.bid(name:leaseName, amount: amount, vaultType: self.ftVaultType, validUntil: validUntil, saleItemExtraField: {}, bidExtraField: {})\n }\n}" }, "bidLeaseMarketDirectOfferSoftDapper": { "spec": { @@ -838,16 +852,16 @@ "spec": { "parameters": { "addon": "String", - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", "addon", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xf8d6e0586b0a20c7\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\n\n\ntransaction(name: String, addon:String, amount:UFix64) {\n\n let leases : \u0026FIND.LeaseCollection?\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FUSD.Vault? \n\n prepare(account: auth (BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n self.leases= account.storage.borrow\u003c\u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n self.vaultRef = account.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n\n }\n\n pre{\n self.leases != nil : \"Could not borrow reference to the leases collection\"\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n }\n\n execute {\n let vault \u003c- self.vaultRef!.withdraw(amount: amount) as! @FUSD.Vault\n self.leases!.buyAddon(name: name, addon: addon, vault: \u003c- vault)\n }\n}" + "code": "import FIND from 0xf3fcd2c1a78f5eee\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FungibleToken from 0xee82856bf20e2aa6\n\n\ntransaction(name: String, addon:String, maxAmount:UFix64) {\n\n let leases : \u0026FIND.LeaseCollection?\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FlowToken.Vault? \n let cost: UFix64\n\n prepare(account: auth (BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n self.leases= account.storage.borrow\u003c\u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n self.vaultRef = account.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.cost=FIND.calculateAddonCostInFlow(addon)\n }\n\n pre{\n self.leases != nil : \"Could not borrow reference to the leases collection\"\n self.vaultRef != nil : \"Could not borrow reference to the flow token vault!\"\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.vaultRef!.balance.toString().concat(\" total balance is \").concat(self.vaultRef!.balance.toString()))\n }\n\n execute {\n let vault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n self.leases!.buyAddon(name: name, addon: addon, vault: \u003c- vault)\n }\n}" }, "buyAddonDapper": { "spec": { @@ -883,6 +897,19 @@ }, "code": "import FindPack from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FUSD from 0xf8d6e0586b0a20c7\nimport Profile from 0xf3fcd2c1a78f5eee\n\ntransaction(packTypeName: String, packTypeId:UInt64, numberOfPacks:UInt64, totalAmount: UFix64) {\n let packs: \u0026FindPack.Collection\n\n let userPacks: Capability\u003c\u0026FindPack.Collection\u003e\n let salePrice: UFix64\n let packsLeft: UInt64\n\n let userFlowTokenVault: auth(FungibleToken.Withdraw) \u0026FlowToken.Vault\n\n let paymentVault: @{FungibleToken.Vault}\n let balanceBeforeTransfer:UFix64\n\n prepare(account: auth (StorageCapabilities, SaveValue,PublishCapability, BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n\n let col = account.storage.borrow\u003c\u0026FindPack.Collection\u003e(from: FindPack.CollectionStoragePath)\n if col == nil {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType:Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:account.address.toString(), createdAt: \"find\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n\n profile.addWallet(fusdWallet)\n\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n profile.addWallet(flowWallet)\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n }\n\n self.userPacks=account.capabilities.get\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionPublicPath)\n self.packs=FindPack.getPacksCollection(packTypeName: packTypeName, packTypeId:packTypeId)\n\n self.salePrice= FindPack.getCurrentPrice(packTypeName: packTypeName, packTypeId:packTypeId, user:account.address) ?? panic (\"Cannot buy the pack now\") \n self.packsLeft= UInt64(self.packs.getPacksLeft())\n\n\n self.userFlowTokenVault = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault) ?? panic(\"Cannot borrow FlowToken vault from account storage\")\n self.balanceBeforeTransfer = self.userFlowTokenVault.balance\n\n if self.balanceBeforeTransfer \u003c totalAmount {\n panic(\"Your account does not have enough funds has \".concat(self.balanceBeforeTransfer.toString()).concat(\" needs \").concat(totalAmount.toString()))\n }\n self.paymentVault \u003c- self.userFlowTokenVault.withdraw(amount: totalAmount)\n }\n\n pre {\n self.salePrice * UFix64(numberOfPacks) == totalAmount: \"unexpected sending amount\"\n self.packsLeft \u003e= numberOfPacks : \"Rats! there are no packs left\"\n self.userPacks.check() : \"User need a receiver to put the pack in\"\n }\n\n execute {\n var counter = numberOfPacks\n while counter \u003e 0 {\n let purchasingVault \u003c- self.paymentVault.withdraw(amount: self.salePrice)\n self.packs.buy(packTypeName: packTypeName, typeId:packTypeId, vault: \u003c- purchasingVault, collectionCapability: self.userPacks)\n counter = counter - 1\n }\n if self.paymentVault.balance != 0.0 {\n panic(\"paymentVault balance is non-zero after paying\")\n }\n destroy self.paymentVault\n }\n\n}" }, + "buyLeaseForSale": { + "spec": { + "parameters": { + "amount": "UFix64", + "leaseName": "String" + }, + "order": [ + "leaseName", + "amount" + ] + }, + "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FIND from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketSale from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, amount: UFix64) {\n\n let buyer : Address\n let walletReference : auth(FungibleToken.Withdraw) \u0026{FungibleToken.Vault}\n\n let saleItemCollection: \u0026{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic}\n\n prepare(account: auth(BorrowValue, SaveValue, IssueStorageCapabilityController) \u0026Account) {\n\n let profile=account.storage.borrow\u003c\u0026Profile.User\u003e(from: Profile.storagePath) ?? panic(\"You do not have a profile set up, initialize the user first\")\n\n let address = FIND.resolve(leaseName) ?? panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))\n\n if address == nil {\n panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))\n }\n\n let leaseMarketplace = FindMarket.getTenantAddress(\"find\") ?? panic(\"Cannot find find tenant\")\n let saleItemsCap= FindLeaseMarketSale.getSaleItemCapability(marketplace: leaseMarketplace, user:address) ?? panic(\"cannot find sale item cap for find\")\n\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=FindMarket.getPublicPath(leaseSaleItemType, name: \"find\")\n let leaseStoragePath= FindMarket.getStoragePath(leaseSaleItemType, name:\"find\")\n var leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check(){\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath)\n leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n }\n\n self.saleItemCollection = saleItemsCap.borrow()!\n let item = self.saleItemCollection.borrowSaleItem(leaseName)\n\n let ft = FTRegistry.getFTInfoByTypeIdentifier(item.getFtType().identifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(item.getFtType().identifier))\n\n\n self.walletReference = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n self.buyer = account.address\n }\n\n pre {\n self.walletReference.balance \u003e amount : \"Your wallet does not have enough funds to pay for this item\"\n }\n\n execute {\n let vault \u003c- self.walletReference.withdraw(amount: amount)\n self.saleItemCollection.buy(name:leaseName, vault: \u003c- vault, to: self.buyer)\n }\n}" + }, "buyLeaseForSaleDapper": { "spec": { "parameters": { @@ -1103,7 +1130,7 @@ "name" ] }, - "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FiatToken from 0xf8d6e0586b0a20c7\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FindPack from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindMarketDirectOfferEscrow from 0xf3fcd2c1a78f5eee\nimport Dandy from 0xf3fcd2c1a78f5eee\n//import \"FindThoughts\"\n\ntransaction(name: String) {\n prepare(account: auth (Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n //if we do not have a profile it might be stored under a different address so we will just remove it\n let profileCapFirst = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if profileCapFirst.check() {\n return \n }\n\n //the code below has some dead code for this specific transaction, but it is hard to maintain otherwise\n //SYNC with register\n //Add exising FUSD or create a new one and add it\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n let usdcCap = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n if !usdcCap.check() {\n account.storage.save( \u003c-FiatToken.createEmptyVault(), to: FiatToken.VaultStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FiatToken.Vault\u003e(FiatToken.VaultStoragePath)\n account.capabilities.publish(cap, at: FiatToken.VaultUUIDPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultReceiverPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultBalancePubPath)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check(){\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026Dandy.Collection\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(cap, at: Dandy.CollectionPublicPath)\n }\n\n let findPackCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(FindPack.CollectionPublicPath)\n if !findPackCap.check() {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType: Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026Profile.User\u003e(Profile.publicPath)\n if !profileCap.check(){\n let newProfile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-newProfile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n if !profile.hasWallet(\"Flow\") {\n let flowWallet=Profile.Wallet( name:\"Flow\", receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver), balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance), accept: Type\u003c@FlowToken.Vault\u003e(), tags: [\"flow\"])\n\n profile.addWallet(flowWallet)\n updated=true\n }\n if !profile.hasWallet(\"FUSD\") {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance)\n profile.addWallet(Profile.Wallet( name:\"FUSD\", receiver:fr, balance:fb, accept: Type\u003c@FUSD.Vault\u003e(), tags: [\"fusd\", \"stablecoin\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"USDC\") {\n\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(FiatToken.VaultBalancePubPath) \n profile.addWallet(Profile.Wallet( name:\"USDC\", receiver:fr, balance:fb, accept: Type\u003c@FiatToken.Vault\u003e(), tags: [\"usdc\", \"stablecoin\"]))\n updated=true\n }\n\n /*\n //If find name not set and we have a profile set it.\n if profile.getFindName() == \"\" {\n if let findName = FIND.reverseLookup(account.address) {\n profile.setFindName(findName)\n // If name is set, it will emit Updated Event, there is no need to emit another update event below. \n updated=false\n }\n }\n */\n\n if created {\n profile.emitCreatedEvent()\n } else if updated {\n profile.emitUpdatedEvent()\n }\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let doeSaleType= Type\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e()\n let doeSalePublicPath=FindMarket.getPublicPath(doeSaleType, name: tenant.name)\n let doeSaleStoragePath= FindMarket.getStoragePath(doeSaleType, name:tenant.name)\n let doeSaleCap= account.capabilities.get\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic}\u003e(doeSalePublicPath) \n if !doeSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferEscrow.createEmptySaleItemCollection(tenantCapability), to: doeSaleStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic, FindMarket.SaleItemCollectionPublic}\u003e(doeSaleStoragePath)\n account.capabilities.publish(cap, at: doeSalePublicPath)\n }\n }\n}" + "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FiatToken from 0xf8d6e0586b0a20c7\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FindPack from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindMarketDirectOfferEscrow from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport Dandy from 0xf3fcd2c1a78f5eee\n\ntransaction(name: String) {\n prepare(account: auth (Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n //if we do not have a profile it might be stored under a different address so we will just remove it\n let profileCapFirst = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if profileCapFirst.check() {\n return \n }\n\n //the code below has some dead code for this specific transaction, but it is hard to maintain otherwise\n //SYNC with register\n //Add exising FUSD or create a new one and add it\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n let usdcCap = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n if !usdcCap.check() {\n account.storage.save( \u003c-FiatToken.createEmptyVault(), to: FiatToken.VaultStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FiatToken.Vault\u003e(FiatToken.VaultStoragePath)\n account.capabilities.publish(cap, at: FiatToken.VaultUUIDPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultReceiverPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultBalancePubPath)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026Dandy.Collection\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(cap, at: Dandy.CollectionPublicPath)\n }\n\n let findPackCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(FindPack.CollectionPublicPath)\n if !findPackCap.check() {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType: Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026Profile.User\u003e(Profile.publicPath)\n if !profileCap.check(){\n let newProfile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-newProfile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n if !profile.hasWallet(\"Flow\") {\n let flowWallet=Profile.Wallet( name:\"Flow\", receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver), balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance), accept: Type\u003c@FlowToken.Vault\u003e(), tags: [\"flow\"])\n\n profile.addWallet(flowWallet)\n updated=true\n }\n if !profile.hasWallet(\"FUSD\") {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance)\n profile.addWallet(Profile.Wallet( name:\"FUSD\", receiver:fr, balance:fb, accept: Type\u003c@FUSD.Vault\u003e(), tags: [\"fusd\", \"stablecoin\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"USDC\") {\n\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(FiatToken.VaultBalancePubPath) \n profile.addWallet(Profile.Wallet( name:\"USDC\", receiver:fr, balance:fb, accept: Type\u003c@FiatToken.Vault\u003e(), tags: [\"usdc\", \"stablecoin\"]))\n updated=true\n }\n\n /*\n //If find name not set and we have a profile set it.\n if profile.getFindName() == \"\" {\n if let findName = FIND.reverseLookup(account.address) {\n profile.setFindName(findName)\n // If name is set, it will emit Updated Event, there is no need to emit another update event below. \n updated=false\n }\n }\n */\n\n if created {\n profile.emitCreatedEvent()\n } else if updated {\n profile.emitUpdatedEvent()\n }\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let doeSaleType= Type\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e()\n let doeSalePublicPath=FindMarket.getPublicPath(doeSaleType, name: tenant.name)\n let doeSaleStoragePath= FindMarket.getStoragePath(doeSaleType, name:tenant.name)\n let doeSaleCap= account.capabilities.get\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic}\u003e(doeSalePublicPath) \n if !doeSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferEscrow.createEmptySaleItemCollection(tenantCapability), to: doeSaleStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic, FindMarket.SaleItemCollectionPublic}\u003e(doeSaleStoragePath)\n account.capabilities.publish(cap, at: doeSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n\n }\n}" }, "createProfileDapper": { "spec": { @@ -1114,7 +1141,7 @@ "name" ] }, - "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FIND from 0xf3fcd2c1a78f5eee\nimport Dandy from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport DapperUtilityCoin from 0x179b6b1cb6755e31\nimport FlowUtilityToken from 0x179b6b1cb6755e31\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport TokenForwarding from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\n\ntransaction(name: String) {\n prepare(account: auth(Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let leaseCollectionCap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(leaseCollectionCap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save\u003c@{NonFungibleToken.Collection}\u003e(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let dandyCollectionCap = account.capabilities.storage.issue\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(dandyCollectionCap, at: Dandy.CollectionPublicPath) \n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n let profileCap = account.capabilities.storage.issue\u003c\u0026{Profile.Public}\u003e(Profile.storagePath)\n account.capabilities.publish(profileCap, at: Profile.publicPath)\n let receiverCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.storagePath)\n account.capabilities.publish(receiverCap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n let dapper=getAccount(FindViews.getDapperAddress())\n\n if !profile.hasWallet(\"DUC\") {\n var ducReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver)\n var ducBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/dapperUtilityCoinVault)\n profile.addWallet(Profile.Wallet( name:\"DUC\", receiver:ducReceiver, balance: ducBalanceCap, accept: Type\u003c@DapperUtilityCoin.Vault\u003e(), tags: [\"duc\", \"dapperUtilityCoin\",\"dapper\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"FUT\") {\n var futReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver)\n var futBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowUtilityTokenBalance)\n if !futReceiver.check() {\n // Create a new Forwarder resource for FUT and store it in the new account's storage\n let futForwarder \u003c- TokenForwarding.createNewForwarder(recipient: dapper.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver))\n account.storage.save(\u003c-futForwarder, to: /storage/flowUtilityTokenReceiver)\n futReceiver = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/flowUtilityTokenReceiver)\n account.capabilities.publish(futReceiver, at: /public/flowUtilityTokenReceiver)\n }\n if !futBalanceCap.check() {\n futBalanceCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/flowUtilityTokenVault)\n account.capabilities.publish(futBalanceCap, at: /public/flowUtilityTokenBalance)\n }\n profile.addWallet(Profile.Wallet( name:\"FUT\", receiver:futReceiver, balance:futBalanceCap, accept: Type\u003c@FlowUtilityToken.Vault\u003e(), tags: [\"fut\", \"flowUtilityToken\",\"dapper\"]))\n updated=true\n }\n\n profile.emitCreatedEvent()\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let dosSaleType= Type\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e()\n let dosSalePublicPath=FindMarket.getPublicPath(dosSaleType, name: tenant.name)\n let dosSaleStoragePath= FindMarket.getStoragePath(dosSaleType, name:tenant.name)\n let dosSaleCap= account.capabilities.get\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSalePublicPath)\n if !dosSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferSoft.createEmptySaleItemCollection(tenantCapability), to: dosSaleStoragePath)\n let dosSaleCap= account.capabilities.storage.issue\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSaleStoragePath)\n account.capabilities.publish(dosSaleCap, at: dosSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" + "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport NonFungibleToken from 0xf8d6e0586b0a20c7\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FIND from 0xf3fcd2c1a78f5eee\nimport Dandy from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport DapperUtilityCoin from 0x179b6b1cb6755e31\nimport FlowUtilityToken from 0x179b6b1cb6755e31\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport TokenForwarding from 0xf8d6e0586b0a20c7\nimport FindViews from 0xf3fcd2c1a78f5eee\n\ntransaction(name: String) {\n prepare(account: auth(Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let leaseCollectionCap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(leaseCollectionCap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save\u003c@{NonFungibleToken.Collection}\u003e(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let dandyCollectionCap = account.capabilities.storage.issue\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(dandyCollectionCap, at: Dandy.CollectionPublicPath) \n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n let profileCap = account.capabilities.storage.issue\u003c\u0026{Profile.Public}\u003e(Profile.storagePath)\n account.capabilities.publish(profileCap, at: Profile.publicPath)\n let receiverCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.storagePath)\n account.capabilities.publish(receiverCap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n let dapper=getAccount(FindViews.getDapperAddress())\n\n if !profile.hasWallet(\"DUC\") {\n var ducReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver)\n var ducBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/dapperUtilityCoinVault)\n profile.addWallet(Profile.Wallet( name:\"DUC\", receiver:ducReceiver, balance: ducBalanceCap, accept: Type\u003c@DapperUtilityCoin.Vault\u003e(), tags: [\"duc\", \"dapperUtilityCoin\",\"dapper\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"FUT\") {\n var futReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver)\n var futBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowUtilityTokenBalance)\n if !futReceiver.check() {\n // Create a new Forwarder resource for FUT and store it in the new account's storage\n let futForwarder \u003c- TokenForwarding.createNewForwarder(recipient: dapper.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver))\n account.storage.save(\u003c-futForwarder, to: /storage/flowUtilityTokenReceiver)\n futReceiver = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/flowUtilityTokenReceiver)\n account.capabilities.publish(futReceiver, at: /public/flowUtilityTokenReceiver)\n }\n if !futBalanceCap.check() {\n futBalanceCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/flowUtilityTokenVault)\n account.capabilities.publish(futBalanceCap, at: /public/flowUtilityTokenBalance)\n }\n profile.addWallet(Profile.Wallet( name:\"FUT\", receiver:futReceiver, balance:futBalanceCap, accept: Type\u003c@FlowUtilityToken.Vault\u003e(), tags: [\"fut\", \"flowUtilityToken\",\"dapper\"]))\n updated=true\n }\n\n profile.emitCreatedEvent()\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let dosSaleType= Type\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e()\n let dosSalePublicPath=FindMarket.getPublicPath(dosSaleType, name: tenant.name)\n let dosSaleStoragePath= FindMarket.getStoragePath(dosSaleType, name:tenant.name)\n let dosSaleCap= account.capabilities.get\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSalePublicPath)\n if !dosSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferSoft.createEmptySaleItemCollection(tenantCapability), to: dosSaleStoragePath)\n let dosSaleCap= account.capabilities.storage.issue\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSaleStoragePath)\n account.capabilities.publish(dosSaleCap, at: dosSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" }, "deleteFindThoughts": { "spec": { @@ -1223,7 +1250,7 @@ "removeLinks" ] }, - "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FIND from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\n\ntransaction(name:String, description: String, avatar: String, tags:[String], allowStoringFollowers: Bool, linkTitles : {String: String}, linkTypes: {String:String}, linkUrls : {String:String}, removeLinks : [String]) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check() {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n }\n\n execute{\n self.profile.setName(name)\n self.profile.setDescription(description)\n self.profile.setAvatar(avatar)\n self.profile.setTags(tags)\n\n for link in removeLinks {\n self.profile.removeLink(link)\n }\n\n for titleName in linkTitles.keys {\n let title=linkTitles[titleName]!\n let url = linkUrls[titleName]!\n let type = linkTypes[titleName]!\n\n self.profile.addLinkWithName(name:titleName, link: Profile.Link(title: title, type: type, url: url))\n }\n self.profile.emitUpdatedEvent()\n }\n}" + "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FIND from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\n\ntransaction(name:String, description: String, avatar: String, tags:[String], allowStoringFollowers: Bool, linkTitles : {String: String}, linkTypes: {String:String}, linkUrls : {String:String}, removeLinks : [String]) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n\n execute{\n self.profile.setName(name)\n self.profile.setDescription(description)\n self.profile.setAvatar(avatar)\n self.profile.setTags(tags)\n\n for link in removeLinks {\n self.profile.removeLink(link)\n }\n\n for titleName in linkTitles.keys {\n let title=linkTitles[titleName]!\n let url = linkUrls[titleName]!\n let type = linkTypes[titleName]!\n\n self.profile.addLinkWithName(name:titleName, link: Profile.Link(title: title, type: type, url: url))\n }\n self.profile.emitUpdatedEvent()\n }\n}" }, "editProfileDapper": { "spec": { @@ -1261,7 +1288,7 @@ "follows" ] }, - "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FIND from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\n\n// map of {User in string (find name or address) : [tag]}\ntransaction(follows:{String : [String]}) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check(){\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check(){\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n\n }\n\n execute{\n for key in follows.keys {\n let user = FIND.resolve(key) ?? panic(key.concat(\" cannot be resolved. It is either an invalid .find name or address\"))\n let tags = follows[key]!\n self.profile.follow(user, tags: tags)\n }\n }\n}" + "code": "import FungibleToken from 0xee82856bf20e2aa6\nimport FUSD from 0xf8d6e0586b0a20c7\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FIND from 0xf3fcd2c1a78f5eee\nimport Profile from 0xf3fcd2c1a78f5eee\n\n// map of {User in string (find name or address) : [tag]}\ntransaction(follows:{String : [String]}) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check(){\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n }\n\n execute{\n for key in follows.keys {\n let user = FIND.resolve(key) ?? panic(key.concat(\" cannot be resolved. It is either an invalid .find name or address\"))\n let tags = follows[key]!\n self.profile.follow(user, tags: tags)\n }\n }\n}" }, "fulfillLeaseMarketAuctionSoft": { "spec": { @@ -1603,6 +1630,13 @@ }, "code": "import TokenForwarding from 0xf8d6e0586b0a20c7\nimport FungibleToken from 0xee82856bf20e2aa6\n\n\ntransaction() {\n prepare(account: auth(BorrowValue) \u0026Account) {\n account.unlink(/public/dapperUtilityCoinReceiver)\n account.link\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver,target: /storage/dapperUtilityCoinVault)\n }\n}" }, + "linkForLeaseMarket": { + "spec": { + "parameters": {}, + "order": [] + }, + "code": "import FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport FindMarket from 0xf3fcd2c1a78f5eee\n\ntransaction() {\n prepare(account: auth (StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" + }, "listLeaseForAuctionSoft": { "spec": { "parameters": { @@ -1626,7 +1660,7 @@ "auctionValidUntil" ] }, - "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketAuctionSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, PublishCapability,Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" + "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketAuctionSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, PublishCapability,Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" }, "listLeaseForAuctionSoftDapper": { "spec": { @@ -1653,6 +1687,23 @@ }, "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketAuctionSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" }, + "listLeaseForSale": { + "spec": { + "parameters": { + "directSellPrice": "UFix64", + "ftAliasOrIdentifier": "String", + "leaseName": "String", + "validUntil": "UFix64?" + }, + "order": [ + "leaseName", + "ftAliasOrIdentifier", + "directSellPrice", + "validUntil" + ] + }, + "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketSale from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FindMarketSale from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" + }, "listLeaseForSaleDapper": { "spec": { "parameters": { @@ -1668,7 +1719,7 @@ "validUntil" ] }, - "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketSale from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FindMarketSale from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" + "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FTRegistry from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketSale from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarket from 0xf3fcd2c1a78f5eee\nimport FindMarketSale from 0xf3fcd2c1a78f5eee\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" }, "listNFTForAuctionEscrowed": { "spec": { @@ -1965,15 +2016,15 @@ "register": { "spec": { "parameters": { - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xf8d6e0586b0a20c7\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\n\ntransaction(name: String, amount: UFix64) {\n\n let vaultRef : auth(FungibleToken.Withdraw) \u0026FUSD.Vault?\n let leases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection?\n let price : UFix64\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n\n self.price=FIND.calculateCost(name)\n log(\"The cost for registering this name is \".concat(self.price.toString()))\n self.vaultRef = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n self.leases=account.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath)\n }\n\n pre{\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.leases != nil : \"Could not borrow reference to find lease collection\"\n self.price == amount : \"Calculated cost : \".concat(self.price.toString()).concat(\" does not match expected cost : \").concat(amount.toString())\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.price) as! @FUSD.Vault\n\n //TODO: entitlements\n self.leases!.register(name: name, vault: \u003c- payVault)\n }\n}" + "code": "import FlowToken from 0x0ae53cb6e3f42a79\nimport FIND from 0xf3fcd2c1a78f5eee\nimport FungibleToken from 0xee82856bf20e2aa6\n\ntransaction(name: String, maxAmount: UFix64) {\n\n let vaultRef : auth(FungibleToken.Withdraw) \u0026FlowToken.Vault?\n let leases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection?\n let cost : UFix64\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n\n self.vaultRef = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.leases=account.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath)\n\n self.cost = FIND.calculateCostInFlow(name)\n\n }\n\n\n pre{\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.leases != nil : \"Could not borrow reference to find lease collection\"\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.cost.toString()).concat(\" total balance is \").concat(self.vaultRef!.balance.toString())\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n self.leases!.register(name: name, vault: \u003c- payVault)\n }\n}" }, "registerFindPackMetadata": { "spec": { @@ -2153,15 +2204,15 @@ "renewName": { "spec": { "parameters": { - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xf8d6e0586b0a20c7\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FIND from 0xf3fcd2c1a78f5eee\n\ntransaction(name: String, amount: UFix64) {\n\n let price : UFix64\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FUSD.Vault? \n let finLeases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection? \n\n prepare(acct: auth(BorrowValue) \u0026Account) {\n self.price=FIND.calculateCost(name)\n self.vaultRef = acct.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n self.finLeases= acct.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n }\n\n pre{\n self.price == amount : \"expected renew cost : \".concat(self.price.toString()).concat(\" is not the same as calculated renew cost : \").concat(amount.toString())\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.finLeases != nil : \"Could not borrow reference to find lease collection\"\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.price) \n let finToken= self.finLeases!.borrow(name)\n finToken.extendLease(\u003c- payVault)\n }\n}" + "code": "import FlowToken from 0x0ae53cb6e3f42a79\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FIND from 0xf3fcd2c1a78f5eee\n\ntransaction(name: String, maxAmount: UFix64) {\n\n let cost : UFix64\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FlowToken.Vault? \n let finLeases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection? \n\n prepare(acct: auth(BorrowValue) \u0026Account) {\n self.cost=FIND.calculateCostInFlow(name)\n self.vaultRef = acct.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.finLeases= acct.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n }\n\n\n pre{\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.finLeases != nil : \"Could not borrow reference to find lease collection\"\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.vaultRef!.balance.toString().concat(\" total balance is \").concat(self.vaultRef!.balance.toString()))\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n let finToken= self.finLeases!.borrow(name)\n finToken.extendLease(\u003c- payVault)\n }\n}" }, "retractOfferLeaseMarketDirectOfferSoft": { "spec": { @@ -2461,6 +2512,21 @@ }, "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport DapperUtilityCoin from 0x179b6b1cb6755e31\nimport FlowUtilityToken from 0x179b6b1cb6755e31\nimport FindLeaseMarketSale from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketAuctionSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FungibleTokenSwitchboard from 0xee82856bf20e2aa6\n\ntransaction(nftName: String, nftType: String, cut: UFix64){\n prepare(account: auth(BorrowValue) \u0026Account){\n\n let defaultRules : [FindMarket.TenantRule] = [\n FindMarket.TenantRule(\n name: \"Dapper\",\n types:[Type\u003c@DapperUtilityCoin.Vault\u003e(), Type\u003c@FlowUtilityToken.Vault\u003e()],\n ruleType: \"ft\",\n allow:true\n ),\n FindMarket.TenantRule(\n name: \"Soft\",\n types:[Type\u003c@FindLeaseMarketSale.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketAuctionSoft.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItem\u003e()\n ],\n ruleType: \"listing\",\n allow:true\n )\n ]\n\n defaultRules.append(\n FindMarket.TenantRule(\n name: nftName,\n types:[CompositeType(nftType)!],\n ruleType: \"nft\",\n allow:true\n )\n )\n\n var royalty : MetadataViews.Royalty? = nil\n if cut != 0.0 {\n royalty = MetadataViews.Royalty(\n receiver: account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FungibleTokenSwitchboard.ReceiverPublicPath)!,\n cut: cut,\n description: \"tenant\"\n )\n }\n\n let saleItem = FindMarket.TenantSaleItem(\n name: \"Dapper\".concat(nftName).concat(\"Soft\"),\n cut: royalty,\n rules: defaultRules,\n status: \"active\"\n )\n\n let clientRef = account.storage.borrow\u003cauth(FindMarket.TenantClientOwner) \u0026FindMarket.TenantClient\u003e(from: FindMarket.TenantClientStoragePath) ?? panic(\"Cannot borrow Tenant Client Reference.\")\n clientRef.setMarketOption(saleItem: saleItem)\n }\n}" }, + "tenantsetLeaseOptionMarket": { + "spec": { + "parameters": { + "cut": "UFix64", + "nftName": "String", + "nftType": "String" + }, + "order": [ + "nftName", + "nftType", + "cut" + ] + }, + "code": "import FindMarket from 0xf3fcd2c1a78f5eee\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FindLeaseMarketSale from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketAuctionSoft from 0xf3fcd2c1a78f5eee\nimport FindLeaseMarketDirectOfferSoft from 0xf3fcd2c1a78f5eee\nimport MetadataViews from 0xf8d6e0586b0a20c7\nimport FungibleToken from 0xee82856bf20e2aa6\nimport FungibleTokenSwitchboard from 0xee82856bf20e2aa6\n\ntransaction(nftName: String, nftType: String, cut: UFix64){\n prepare(account: auth(BorrowValue) \u0026Account){\n\n let defaultRules : [FindMarket.TenantRule] = [\n FindMarket.TenantRule(\n name: \"Flow\",\n types:[Type\u003c@FlowToken.Vault\u003e()],\n ruleType: \"ft\",\n allow:true\n ),\n FindMarket.TenantRule(\n name: \"Soft\",\n types:[Type\u003c@FindLeaseMarketSale.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketAuctionSoft.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItem\u003e()\n ],\n ruleType: \"listing\",\n allow:true\n )\n ]\n\n defaultRules.append(\n FindMarket.TenantRule(\n name: nftName,\n types:[CompositeType(nftType)!],\n ruleType: \"nft\",\n allow:true\n )\n )\n\n var royalty : MetadataViews.Royalty? = nil\n if cut != 0.0 {\n royalty = MetadataViews.Royalty(\n receiver: account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FungibleTokenSwitchboard.ReceiverPublicPath),\n cut: cut,\n description: \"tenant\"\n )\n }\n\n let saleItem = FindMarket.TenantSaleItem(\n name: \"Flow\".concat(nftName).concat(\"Soft\"),\n cut: royalty,\n rules: defaultRules,\n status: \"active\"\n )\n\n let clientRef = account.storage.borrow\u003cauth(FindMarket.TenantClientOwner) \u0026FindMarket.TenantClient\u003e(from: FindMarket.TenantClientStoragePath) ?? panic(\"Cannot borrow Tenant Client Reference.\")\n clientRef.setMarketOption(saleItem: saleItem)\n }\n}" + }, "tenantsetMarketOption": { "spec": { "parameters": { @@ -2691,7 +2757,7 @@ "user" ] }, - "code": "import FIND from 0x35717efbbce11c74\nimport FUSD from 0xe223d8a629e49c68\nimport FindMarket from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\n\naccess(all) struct FINDReport{\n\n access(all) let leases: [FIND.LeaseInformation]\n access(all) let leasesBids: [FIND.BidInfo]\n access(all) let itemsForSale: {String : FindMarket.SaleItemCollectionReport}\n access(all) let marketBids: {String : FindMarket.BidItemCollectionReport}\n\n init(\n bids: [FIND.BidInfo],\n leases : [FIND.LeaseInformation],\n leasesBids: [FIND.BidInfo],\n itemsForSale: {String : FindMarket.SaleItemCollectionReport},\n marketBids: {String : FindMarket.BidItemCollectionReport},\n ) {\n\n self.leases=leases\n self.leasesBids=leasesBids\n self.itemsForSale=itemsForSale\n self.marketBids=marketBids\n }\n}\n\n\naccess(all) fun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n let bidCap=account.capabilities.borrow\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n let leaseCap = account.capabilities.borrow\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n\n let leases = leaseCap?.getLeaseInformation() ?? []\n let oldLeaseBid = bidCap?.getBids() ?? []\n\n let find= FindMarket.getFindTenantAddress()\n var items : {String : FindMarket.SaleItemCollectionReport} = FindMarket.getSaleItemReport(tenant:find, address: address, getNFTInfo:true)\n var marketBids : {String : FindMarket.BidItemCollectionReport} = FindMarket.getBidsReport(tenant:find, address: address, getNFTInfo:true)\n\n return FINDReport(\n bids: oldLeaseBid,\n leases: leases,\n leasesBids: oldLeaseBid,\n itemsForSale: items,\n marketBids: marketBids,\n )\n}" + "code": "import FIND from 0x35717efbbce11c74\nimport FUSD from 0xe223d8a629e49c68\nimport FindMarket from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\n\naccess(all) struct FINDReport{\n\n access(all) let leases: [FIND.LeaseInformation]\n access(all) let leasesBids: [FIND.BidInfo]\n access(all) let itemsForSale: {String : FindMarket.SaleItemCollectionReport}\n access(all) let marketBids: {String : FindMarket.BidItemCollectionReport}\n\n init(\n bids: [FIND.BidInfo],\n leases : [FIND.LeaseInformation],\n leasesBids: [FIND.BidInfo],\n itemsForSale: {String : FindMarket.SaleItemCollectionReport},\n marketBids: {String : FindMarket.BidItemCollectionReport},\n ) {\n\n self.leases=leases\n self.leasesBids=leasesBids\n self.itemsForSale=itemsForSale\n self.marketBids=marketBids\n }\n}\n\n\naccess(all) fun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n let leaseCap = account.capabilities.borrow\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n let leases = leaseCap?.getLeaseInformation() ?? []\n let find= FindMarket.getFindTenantAddress()\n var items : {String : FindMarket.SaleItemCollectionReport} = FindMarket.getSaleItemReport(tenant:find, address: address, getNFTInfo:true)\n var marketBids : {String : FindMarket.BidItemCollectionReport} = FindMarket.getBidsReport(tenant:find, address: address, getNFTInfo:true)\n\n return FINDReport(\n bids: [],\n leases: leases,\n leasesBids: [],\n itemsForSale: items,\n marketBids: marketBids,\n )\n}" }, "getFindNameMarket": { "spec": { @@ -2713,7 +2779,7 @@ "user" ] }, - "code": "import FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindRelatedAccounts from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FindUtils from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\nimport LostAndFound from 0xbe4635353f55bbd4\n\naccess(all) \nstruct FINDReport{\n access(all) let isDapper: Bool\n access(all) let profile:Profile.UserReport?\n access(all) let privateMode: Bool\n access(all) let activatedAccount: Bool\n access(all) let hasLostAndFoundItem: Bool\n access(all) let accounts : [AccountInformation]?\n //not sure\n access(all) let readyForWearables : Bool?\n\n init(profile: Profile.UserReport?,\n privateMode: Bool,\n activatedAccount: Bool,\n isDapper: Bool,\n hasLostAndFoundItem: Bool,\n accounts: [AccountInformation]?,\n readyForWearables: Bool?\n) {\n\n self.hasLostAndFoundItem=hasLostAndFoundItem\n self.profile=profile\n self.privateMode=privateMode\n self.activatedAccount=activatedAccount\n self.isDapper=isDapper\n self.accounts=accounts\n self.readyForWearables=readyForWearables\n}\n}\n\naccess(all) struct AccountInformation {\n access(all) let name: String\n access(all) let address: String\n access(all) let network: String\n access(all) let trusted: Bool\n access(all) let node: String\n\n init(name: String, address: String, network: String, trusted: Bool, node: String) {\n self.name = name\n self.address = address\n self.network = network\n self.trusted = trusted\n self.node = node\n }\n}\n\n\naccess(all) \nfun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n //why not auth account here?\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n var isDapper=false\n if let receiver =account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver) {\n isDapper=receiver.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n if let duc = account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver){\n isDapper = duc.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n isDapper = false\n }\n }\n\n let profile=account.capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n var profileReport = profile?.asReport()\n if profileReport != nil \u0026\u0026 profileReport!.findName != FIND.reverseLookup(address) {\n profileReport = Profile.UserReport(\n findName: \"\",\n address: profileReport!.address,\n name: profileReport!.name,\n gender: profileReport!.gender,\n description: profileReport!.description,\n tags: profileReport!.tags,\n avatar: profileReport!.avatar,\n links: profileReport!.links,\n wallets: profileReport!.wallets,\n following: profileReport!.following,\n followers: profileReport!.followers,\n allowStoringFollowers: profileReport!.allowStoringFollowers,\n createdAt: profileReport!.createdAt\n )\n }\n\n let discordID = \"\"//EmeraldIdentity.getDiscordFromAccount(account: address) ?? \"\"\n\n let emeraldIDAccounts : {String : Address} = {}\n //emeraldIDAccounts[\"blocto\"] = EmeraldIdentity.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"lilico\"] = EmeraldIdentityLilico.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"dapper\"] = EmeraldIdentityDapper.getAccountFromDiscord(discordID: discordID)\n\n let accounts : [AccountInformation] = []\n for wallet in [\"blocto\", \"lilico\", \"dapper\"] {\n if let w = emeraldIDAccounts[wallet] {\n if w == address {\n continue\n }\n\n accounts.append(\n AccountInformation(\n name: wallet,\n address: w.toString(),\n network: \"Flow\",\n trusted: true,\n node: \"EmeraldID\")\n )\n }\n }\n\n if let allAcctsCap = FindRelatedAccounts.getCapability(address) {\n let allAcctsRef = allAcctsCap.borrow()!\n let allAccts = allAcctsRef.getAllRelatedAccountInfo()\n for acct in allAccts.values {\n // We only verify flow accounts that are mutually linked\n var trusted = false\n if acct.address != nil {\n if acct.address! == address {\n continue\n }\n trusted = allAcctsRef.linked(name: acct.name, network: acct.network, address: acct.address!)\n }\n accounts.append(AccountInformation(\n name: acct.name,\n address: acct.stringAddress,\n network: acct.network,\n trusted: trusted,\n node: \"FindRelatedAccounts\")\n )\n }\n }\n\n var readyForWearables = false\n var hasLostAndFoundItem : Bool = false\n\n for t in LostAndFound.getRedeemableTypes(address) {\n if t.isSubtype(of: Type\u003c@{NonFungibleToken.NFT}\u003e()) {\n hasLostAndFoundItem = true\n break\n }\n }\n\n return FINDReport(\n profile: profileReport,\n privateMode: profile?.isPrivateModeEnabled() ?? false,\n activatedAccount: true,\n isDapper:isDapper,\n hasLostAndFoundItem: hasLostAndFoundItem,\n accounts: accounts,\n readyForWearables: readyForWearables,\n )\n }" + "code": "import FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindRelatedAccounts from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FindUtils from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\nimport LostAndFound from 0xbe4635353f55bbd4\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\naccess(all) struct FINDReport{\n access(all) let isDapper: Bool\n access(all) let profile:Profile.UserReport?\n access(all) let privateMode: Bool\n access(all) let activatedAccount: Bool\n access(all) let hasLostAndFoundItem: Bool\n access(all) let isReadyForNameOffer: Bool\n access(all) let accounts : [AccountInformation]?\n //not sure\n access(all) let readyForWearables : Bool?\n\n init(profile: Profile.UserReport?,\n privateMode: Bool,\n activatedAccount: Bool,\n isDapper: Bool,\n hasLostAndFoundItem: Bool,\n accounts: [AccountInformation]?,\n readyForWearables: Bool?,\n isReadyForNameOffer: Bool) {\n\n self.hasLostAndFoundItem=hasLostAndFoundItem\n self.profile=profile\n self.privateMode=privateMode\n self.activatedAccount=activatedAccount\n self.isDapper=isDapper\n self.accounts=accounts\n self.readyForWearables=readyForWearables\n self.isReadyForNameOffer=isReadyForNameOffer\n }\n}\n\naccess(all) struct AccountInformation {\n access(all) let name: String\n access(all) let address: String\n access(all) let network: String\n access(all) let trusted: Bool\n access(all) let node: String\n\n init(name: String, address: String, network: String, trusted: Bool, node: String) {\n self.name = name\n self.address = address\n self.network = network\n self.trusted = trusted\n self.node = node\n }\n}\n\n\naccess(all) \nfun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n //why not auth account here?\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n var isDapper=false\n if let receiver =account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver) {\n isDapper=receiver.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n if let duc = account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver){\n isDapper = duc.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n isDapper = false\n }\n }\n\n let profile=account.capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n var profileReport = profile?.asReport()\n if profileReport != nil \u0026\u0026 profileReport!.findName != FIND.reverseLookup(address) {\n profileReport = Profile.UserReport(\n findName: \"\",\n address: profileReport!.address,\n name: profileReport!.name,\n gender: profileReport!.gender,\n description: profileReport!.description,\n tags: profileReport!.tags,\n avatar: profileReport!.avatar,\n links: profileReport!.links,\n wallets: profileReport!.wallets,\n following: profileReport!.following,\n followers: profileReport!.followers,\n allowStoringFollowers: profileReport!.allowStoringFollowers,\n createdAt: profileReport!.createdAt\n )\n }\n\n let discordID = \"\"//EmeraldIdentity.getDiscordFromAccount(account: address) ?? \"\"\n\n let emeraldIDAccounts : {String : Address} = {}\n //emeraldIDAccounts[\"blocto\"] = EmeraldIdentity.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"lilico\"] = EmeraldIdentityLilico.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"dapper\"] = EmeraldIdentityDapper.getAccountFromDiscord(discordID: discordID)\n\n let accounts : [AccountInformation] = []\n for wallet in [\"blocto\", \"lilico\", \"dapper\"] {\n if let w = emeraldIDAccounts[wallet] {\n if w == address {\n continue\n }\n\n accounts.append(\n AccountInformation(\n name: wallet,\n address: w.toString(),\n network: \"Flow\",\n trusted: true,\n node: \"EmeraldID\")\n )\n }\n }\n\n if let allAcctsCap = FindRelatedAccounts.getCapability(address) {\n let allAcctsRef = allAcctsCap.borrow()!\n let allAccts = allAcctsRef.getAllRelatedAccountInfo()\n for acct in allAccts.values {\n // We only verify flow accounts that are mutually linked\n var trusted = false\n if acct.address != nil {\n if acct.address! == address {\n continue\n }\n trusted = allAcctsRef.linked(name: acct.name, network: acct.network, address: acct.address!)\n }\n accounts.append(AccountInformation(\n name: acct.name,\n address: acct.stringAddress,\n network: acct.network,\n trusted: trusted,\n node: \"FindRelatedAccounts\")\n )\n }\n }\n\n var readyForWearables = false\n var hasLostAndFoundItem : Bool = false\n\n for t in LostAndFound.getRedeemableTypes(address) {\n if t.isSubtype(of: Type\u003c@{NonFungibleToken.NFT}\u003e()) {\n hasLostAndFoundItem = true\n break\n }\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n let readyForLeaseOffer =leaseDOSSaleItemCap.check()\n\n return FINDReport(\n profile: profileReport,\n privateMode: profile?.isPrivateModeEnabled() ?? false,\n activatedAccount: true,\n isDapper:isDapper,\n hasLostAndFoundItem: hasLostAndFoundItem,\n accounts: accounts,\n readyForWearables: readyForWearables,\n isReadyForNameOffer: readyForLeaseOffer\n )\n }" }, "getFindThoughts": { "spec": { @@ -3160,7 +3226,7 @@ "leaseName" ] }, - "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n let marketOption = FindMarket.getMarketOptionFromType(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n let item = FindLeaseMarket.assertOperationValid(tenant: marketplace, name: leaseName, marketOption: marketOption)\n let ref = account.capabilities.storage.get\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath) ?? panic(\"Cannot borrow reference to find lease collection. Account : \".concat(account.address.toString()))\n self.pointer= FindLeaseMarket.AuthLeasePointer(ref: ref, name: leaseName)\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n}" + "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n}" }, "acceptLeaseDirectOfferSoftDapper": { "spec": { @@ -3171,7 +3237,7 @@ "leaseName" ] }, - "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n\n}" + "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n\n}" }, "acceptMultipleDirectOfferSoft": { "spec": { @@ -3290,7 +3356,7 @@ "validUntil" ] }, - "code": "import Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, validUntil: UFix64?) {\n\n let bidsReference: \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection?\n let ftVaultType: Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n\n let resolveAddress = FIND.resolve(leaseName)\n if resolveAddress == nil {panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))}\n let address = resolveAddress!\n\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n self.ftVaultType = ft.type\n\n let walletReference = account.storage.borrow\u003c\u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n assert(walletReference.balance \u003e amount , message: \"Bidder has to have enough balance in wallet\")\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)!\n let leaseDOSBidType= Type\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e()\n let leaseDOSBidPublicPath=leaseTenant.getPublicPath(leaseDOSBidType)\n let leaseDOSBidStoragePath= leaseTenant.getStoragePath(leaseDOSBidType)\n let leaseDOSBidCap= account.getCapability\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath)\n if !leaseDOSBidCap.check() {\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptyMarketBidCollection(receiver:receiverCap, tenantCapability:leaseTenantCapability), to: leaseDOSBidStoragePath)\n account.link\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath, target: leaseDOSBidStoragePath)\n }\n\n self.bidsReference= account.storage.borrow\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(from: leaseDOSBidStoragePath)\n\n }\n\n pre {\n self.bidsReference != nil : \"This account does not have a bid collection\"\n }\n\n execute {\n self.bidsReference!.bid(name:leaseName, amount: amount, vaultType: self.ftVaultType, validUntil: validUntil, saleItemExtraField: {}, bidExtraField: {})\n }\n}" + "code": "import Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, validUntil: UFix64?) {\n\n let bidsReference: auth(FindLeaseMarketDirectOfferSoft.Buyer) \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection?\n let ftVaultType: Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n\n let resolveAddress = FIND.resolve(leaseName)\n if resolveAddress == nil {panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))}\n let address = resolveAddress!\n\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n self.ftVaultType = ft.type\n\n let walletReference = account.storage.borrow\u003c\u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n assert(walletReference.balance \u003e amount , message: \"Bidder has to have enough balance in wallet\")\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let leaseDOSBidType= Type\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e()\n let leaseDOSBidPublicPath=leaseTenant.getPublicPath(leaseDOSBidType)\n let leaseDOSBidStoragePath= leaseTenant.getStoragePath(leaseDOSBidType)\n let leaseDOSBidCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath)\n if !leaseDOSBidCap.check() {\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptyMarketBidCollection(receiver:receiverCap, tenantCapability:leaseTenantCapability), to: leaseDOSBidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidStoragePath)\n account.capabilities.publish(cap, at: leaseDOSBidPublicPath)\n }\n\n self.bidsReference= account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Buyer) \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(from: leaseDOSBidStoragePath)\n\n }\n\n pre {\n self.bidsReference != nil : \"This account does not have a bid collection\"\n }\n\n execute {\n self.bidsReference!.bid(name:leaseName, amount: amount, vaultType: self.ftVaultType, validUntil: validUntil, saleItemExtraField: {}, bidExtraField: {})\n }\n}" }, "bidLeaseMarketDirectOfferSoftDapper": { "spec": { @@ -3512,16 +3578,16 @@ "spec": { "parameters": { "addon": "String", - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", "addon", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xe223d8a629e49c68\nimport FIND from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\n\n\ntransaction(name: String, addon:String, amount:UFix64) {\n\n let leases : \u0026FIND.LeaseCollection?\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FUSD.Vault? \n\n prepare(account: auth (BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n self.leases= account.storage.borrow\u003c\u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n self.vaultRef = account.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n\n }\n\n pre{\n self.leases != nil : \"Could not borrow reference to the leases collection\"\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n }\n\n execute {\n let vault \u003c- self.vaultRef!.withdraw(amount: amount) as! @FUSD.Vault\n self.leases!.buyAddon(name: name, addon: addon, vault: \u003c- vault)\n }\n}" + "code": "import FIND from 0x35717efbbce11c74\nimport FlowToken from 0x7e60df042a9c0868\nimport FungibleToken from 0x9a0766d93b6608b7\n\n\ntransaction(name: String, addon:String, maxAmount:UFix64) {\n\n let leases : \u0026FIND.LeaseCollection?\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FlowToken.Vault? \n let cost: UFix64\n\n prepare(account: auth (BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n self.leases= account.storage.borrow\u003c\u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n self.vaultRef = account.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.cost=FIND.calculateAddonCostInFlow(addon)\n }\n\n pre{\n self.leases != nil : \"Could not borrow reference to the leases collection\"\n self.vaultRef != nil : \"Could not borrow reference to the flow token vault!\"\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.vaultRef!.balance.toString().concat(\" total balance is \").concat(self.vaultRef!.balance.toString()))\n }\n\n execute {\n let vault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n self.leases!.buyAddon(name: name, addon: addon, vault: \u003c- vault)\n }\n}" }, "buyAddonDapper": { "spec": { @@ -3557,6 +3623,19 @@ }, "code": "import FindPack from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FlowToken from 0x7e60df042a9c0868\nimport FUSD from 0xe223d8a629e49c68\nimport Profile from 0x35717efbbce11c74\n\ntransaction(packTypeName: String, packTypeId:UInt64, numberOfPacks:UInt64, totalAmount: UFix64) {\n let packs: \u0026FindPack.Collection\n\n let userPacks: Capability\u003c\u0026FindPack.Collection\u003e\n let salePrice: UFix64\n let packsLeft: UInt64\n\n let userFlowTokenVault: auth(FungibleToken.Withdraw) \u0026FlowToken.Vault\n\n let paymentVault: @{FungibleToken.Vault}\n let balanceBeforeTransfer:UFix64\n\n prepare(account: auth (StorageCapabilities, SaveValue,PublishCapability, BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n\n let col = account.storage.borrow\u003c\u0026FindPack.Collection\u003e(from: FindPack.CollectionStoragePath)\n if col == nil {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType:Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:account.address.toString(), createdAt: \"find\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n\n profile.addWallet(fusdWallet)\n\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n profile.addWallet(flowWallet)\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n }\n\n self.userPacks=account.capabilities.get\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionPublicPath)\n self.packs=FindPack.getPacksCollection(packTypeName: packTypeName, packTypeId:packTypeId)\n\n self.salePrice= FindPack.getCurrentPrice(packTypeName: packTypeName, packTypeId:packTypeId, user:account.address) ?? panic (\"Cannot buy the pack now\") \n self.packsLeft= UInt64(self.packs.getPacksLeft())\n\n\n self.userFlowTokenVault = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault) ?? panic(\"Cannot borrow FlowToken vault from account storage\")\n self.balanceBeforeTransfer = self.userFlowTokenVault.balance\n\n if self.balanceBeforeTransfer \u003c totalAmount {\n panic(\"Your account does not have enough funds has \".concat(self.balanceBeforeTransfer.toString()).concat(\" needs \").concat(totalAmount.toString()))\n }\n self.paymentVault \u003c- self.userFlowTokenVault.withdraw(amount: totalAmount)\n }\n\n pre {\n self.salePrice * UFix64(numberOfPacks) == totalAmount: \"unexpected sending amount\"\n self.packsLeft \u003e= numberOfPacks : \"Rats! there are no packs left\"\n self.userPacks.check() : \"User need a receiver to put the pack in\"\n }\n\n execute {\n var counter = numberOfPacks\n while counter \u003e 0 {\n let purchasingVault \u003c- self.paymentVault.withdraw(amount: self.salePrice)\n self.packs.buy(packTypeName: packTypeName, typeId:packTypeId, vault: \u003c- purchasingVault, collectionCapability: self.userPacks)\n counter = counter - 1\n }\n if self.paymentVault.balance != 0.0 {\n panic(\"paymentVault balance is non-zero after paying\")\n }\n destroy self.paymentVault\n }\n\n}" }, + "buyLeaseForSale": { + "spec": { + "parameters": { + "amount": "UFix64", + "leaseName": "String" + }, + "order": [ + "leaseName", + "amount" + ] + }, + "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, amount: UFix64) {\n\n let buyer : Address\n let walletReference : auth(FungibleToken.Withdraw) \u0026{FungibleToken.Vault}\n\n let saleItemCollection: \u0026{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic}\n\n prepare(account: auth(BorrowValue, SaveValue, IssueStorageCapabilityController) \u0026Account) {\n\n let profile=account.storage.borrow\u003c\u0026Profile.User\u003e(from: Profile.storagePath) ?? panic(\"You do not have a profile set up, initialize the user first\")\n\n let address = FIND.resolve(leaseName) ?? panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))\n\n if address == nil {\n panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))\n }\n\n let leaseMarketplace = FindMarket.getTenantAddress(\"find\") ?? panic(\"Cannot find find tenant\")\n let saleItemsCap= FindLeaseMarketSale.getSaleItemCapability(marketplace: leaseMarketplace, user:address) ?? panic(\"cannot find sale item cap for find\")\n\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=FindMarket.getPublicPath(leaseSaleItemType, name: \"find\")\n let leaseStoragePath= FindMarket.getStoragePath(leaseSaleItemType, name:\"find\")\n var leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check(){\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath)\n leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n }\n\n self.saleItemCollection = saleItemsCap.borrow()!\n let item = self.saleItemCollection.borrowSaleItem(leaseName)\n\n let ft = FTRegistry.getFTInfoByTypeIdentifier(item.getFtType().identifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(item.getFtType().identifier))\n\n\n self.walletReference = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n self.buyer = account.address\n }\n\n pre {\n self.walletReference.balance \u003e amount : \"Your wallet does not have enough funds to pay for this item\"\n }\n\n execute {\n let vault \u003c- self.walletReference.withdraw(amount: amount)\n self.saleItemCollection.buy(name:leaseName, vault: \u003c- vault, to: self.buyer)\n }\n}" + }, "buyLeaseForSaleDapper": { "spec": { "parameters": { @@ -3777,7 +3856,7 @@ "name" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport FUSD from 0xe223d8a629e49c68\nimport FiatToken from 0xa983fecbed621163\nimport FlowToken from 0x7e60df042a9c0868\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport FindPack from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferEscrow from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\n//import \"FindThoughts\"\n\ntransaction(name: String) {\n prepare(account: auth (Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n //if we do not have a profile it might be stored under a different address so we will just remove it\n let profileCapFirst = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if profileCapFirst.check() {\n return \n }\n\n //the code below has some dead code for this specific transaction, but it is hard to maintain otherwise\n //SYNC with register\n //Add exising FUSD or create a new one and add it\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n let usdcCap = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n if !usdcCap.check() {\n account.storage.save( \u003c-FiatToken.createEmptyVault(), to: FiatToken.VaultStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FiatToken.Vault\u003e(FiatToken.VaultStoragePath)\n account.capabilities.publish(cap, at: FiatToken.VaultUUIDPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultReceiverPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultBalancePubPath)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check(){\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026Dandy.Collection\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(cap, at: Dandy.CollectionPublicPath)\n }\n\n let findPackCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(FindPack.CollectionPublicPath)\n if !findPackCap.check() {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType: Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026Profile.User\u003e(Profile.publicPath)\n if !profileCap.check(){\n let newProfile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-newProfile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n if !profile.hasWallet(\"Flow\") {\n let flowWallet=Profile.Wallet( name:\"Flow\", receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver), balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance), accept: Type\u003c@FlowToken.Vault\u003e(), tags: [\"flow\"])\n\n profile.addWallet(flowWallet)\n updated=true\n }\n if !profile.hasWallet(\"FUSD\") {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance)\n profile.addWallet(Profile.Wallet( name:\"FUSD\", receiver:fr, balance:fb, accept: Type\u003c@FUSD.Vault\u003e(), tags: [\"fusd\", \"stablecoin\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"USDC\") {\n\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(FiatToken.VaultBalancePubPath) \n profile.addWallet(Profile.Wallet( name:\"USDC\", receiver:fr, balance:fb, accept: Type\u003c@FiatToken.Vault\u003e(), tags: [\"usdc\", \"stablecoin\"]))\n updated=true\n }\n\n /*\n //If find name not set and we have a profile set it.\n if profile.getFindName() == \"\" {\n if let findName = FIND.reverseLookup(account.address) {\n profile.setFindName(findName)\n // If name is set, it will emit Updated Event, there is no need to emit another update event below. \n updated=false\n }\n }\n */\n\n if created {\n profile.emitCreatedEvent()\n } else if updated {\n profile.emitUpdatedEvent()\n }\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let doeSaleType= Type\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e()\n let doeSalePublicPath=FindMarket.getPublicPath(doeSaleType, name: tenant.name)\n let doeSaleStoragePath= FindMarket.getStoragePath(doeSaleType, name:tenant.name)\n let doeSaleCap= account.capabilities.get\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic}\u003e(doeSalePublicPath) \n if !doeSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferEscrow.createEmptySaleItemCollection(tenantCapability), to: doeSaleStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic, FindMarket.SaleItemCollectionPublic}\u003e(doeSaleStoragePath)\n account.capabilities.publish(cap, at: doeSalePublicPath)\n }\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport FUSD from 0xe223d8a629e49c68\nimport FiatToken from 0xa983fecbed621163\nimport FlowToken from 0x7e60df042a9c0868\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport FindPack from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferEscrow from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\n\ntransaction(name: String) {\n prepare(account: auth (Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n //if we do not have a profile it might be stored under a different address so we will just remove it\n let profileCapFirst = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if profileCapFirst.check() {\n return \n }\n\n //the code below has some dead code for this specific transaction, but it is hard to maintain otherwise\n //SYNC with register\n //Add exising FUSD or create a new one and add it\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n let usdcCap = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n if !usdcCap.check() {\n account.storage.save( \u003c-FiatToken.createEmptyVault(), to: FiatToken.VaultStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FiatToken.Vault\u003e(FiatToken.VaultStoragePath)\n account.capabilities.publish(cap, at: FiatToken.VaultUUIDPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultReceiverPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultBalancePubPath)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026Dandy.Collection\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(cap, at: Dandy.CollectionPublicPath)\n }\n\n let findPackCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(FindPack.CollectionPublicPath)\n if !findPackCap.check() {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType: Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026Profile.User\u003e(Profile.publicPath)\n if !profileCap.check(){\n let newProfile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-newProfile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n if !profile.hasWallet(\"Flow\") {\n let flowWallet=Profile.Wallet( name:\"Flow\", receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver), balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance), accept: Type\u003c@FlowToken.Vault\u003e(), tags: [\"flow\"])\n\n profile.addWallet(flowWallet)\n updated=true\n }\n if !profile.hasWallet(\"FUSD\") {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance)\n profile.addWallet(Profile.Wallet( name:\"FUSD\", receiver:fr, balance:fb, accept: Type\u003c@FUSD.Vault\u003e(), tags: [\"fusd\", \"stablecoin\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"USDC\") {\n\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(FiatToken.VaultBalancePubPath) \n profile.addWallet(Profile.Wallet( name:\"USDC\", receiver:fr, balance:fb, accept: Type\u003c@FiatToken.Vault\u003e(), tags: [\"usdc\", \"stablecoin\"]))\n updated=true\n }\n\n /*\n //If find name not set and we have a profile set it.\n if profile.getFindName() == \"\" {\n if let findName = FIND.reverseLookup(account.address) {\n profile.setFindName(findName)\n // If name is set, it will emit Updated Event, there is no need to emit another update event below. \n updated=false\n }\n }\n */\n\n if created {\n profile.emitCreatedEvent()\n } else if updated {\n profile.emitUpdatedEvent()\n }\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let doeSaleType= Type\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e()\n let doeSalePublicPath=FindMarket.getPublicPath(doeSaleType, name: tenant.name)\n let doeSaleStoragePath= FindMarket.getStoragePath(doeSaleType, name:tenant.name)\n let doeSaleCap= account.capabilities.get\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic}\u003e(doeSalePublicPath) \n if !doeSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferEscrow.createEmptySaleItemCollection(tenantCapability), to: doeSaleStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic, FindMarket.SaleItemCollectionPublic}\u003e(doeSaleStoragePath)\n account.capabilities.publish(cap, at: doeSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n\n }\n}" }, "createProfileDapper": { "spec": { @@ -3788,7 +3867,7 @@ "name" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferSoft from 0x35717efbbce11c74\nimport DapperUtilityCoin from 0x82ec283f88a62e65\nimport FlowUtilityToken from 0x82ec283f88a62e65\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FindViews from 0x35717efbbce11c74\n\ntransaction(name: String) {\n prepare(account: auth(Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let leaseCollectionCap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(leaseCollectionCap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save\u003c@{NonFungibleToken.Collection}\u003e(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let dandyCollectionCap = account.capabilities.storage.issue\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(dandyCollectionCap, at: Dandy.CollectionPublicPath) \n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n let profileCap = account.capabilities.storage.issue\u003c\u0026{Profile.Public}\u003e(Profile.storagePath)\n account.capabilities.publish(profileCap, at: Profile.publicPath)\n let receiverCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.storagePath)\n account.capabilities.publish(receiverCap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n let dapper=getAccount(FindViews.getDapperAddress())\n\n if !profile.hasWallet(\"DUC\") {\n var ducReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver)\n var ducBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/dapperUtilityCoinVault)\n profile.addWallet(Profile.Wallet( name:\"DUC\", receiver:ducReceiver, balance: ducBalanceCap, accept: Type\u003c@DapperUtilityCoin.Vault\u003e(), tags: [\"duc\", \"dapperUtilityCoin\",\"dapper\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"FUT\") {\n var futReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver)\n var futBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowUtilityTokenBalance)\n if !futReceiver.check() {\n // Create a new Forwarder resource for FUT and store it in the new account's storage\n let futForwarder \u003c- TokenForwarding.createNewForwarder(recipient: dapper.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver))\n account.storage.save(\u003c-futForwarder, to: /storage/flowUtilityTokenReceiver)\n futReceiver = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/flowUtilityTokenReceiver)\n account.capabilities.publish(futReceiver, at: /public/flowUtilityTokenReceiver)\n }\n if !futBalanceCap.check() {\n futBalanceCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/flowUtilityTokenVault)\n account.capabilities.publish(futBalanceCap, at: /public/flowUtilityTokenBalance)\n }\n profile.addWallet(Profile.Wallet( name:\"FUT\", receiver:futReceiver, balance:futBalanceCap, accept: Type\u003c@FlowUtilityToken.Vault\u003e(), tags: [\"fut\", \"flowUtilityToken\",\"dapper\"]))\n updated=true\n }\n\n profile.emitCreatedEvent()\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let dosSaleType= Type\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e()\n let dosSalePublicPath=FindMarket.getPublicPath(dosSaleType, name: tenant.name)\n let dosSaleStoragePath= FindMarket.getStoragePath(dosSaleType, name:tenant.name)\n let dosSaleCap= account.capabilities.get\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSalePublicPath)\n if !dosSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferSoft.createEmptySaleItemCollection(tenantCapability), to: dosSaleStoragePath)\n let dosSaleCap= account.capabilities.storage.issue\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSaleStoragePath)\n account.capabilities.publish(dosSaleCap, at: dosSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferSoft from 0x35717efbbce11c74\nimport DapperUtilityCoin from 0x82ec283f88a62e65\nimport FlowUtilityToken from 0x82ec283f88a62e65\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FindViews from 0x35717efbbce11c74\n\ntransaction(name: String) {\n prepare(account: auth(Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let leaseCollectionCap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(leaseCollectionCap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save\u003c@{NonFungibleToken.Collection}\u003e(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let dandyCollectionCap = account.capabilities.storage.issue\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(dandyCollectionCap, at: Dandy.CollectionPublicPath) \n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n let profileCap = account.capabilities.storage.issue\u003c\u0026{Profile.Public}\u003e(Profile.storagePath)\n account.capabilities.publish(profileCap, at: Profile.publicPath)\n let receiverCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.storagePath)\n account.capabilities.publish(receiverCap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n let dapper=getAccount(FindViews.getDapperAddress())\n\n if !profile.hasWallet(\"DUC\") {\n var ducReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver)\n var ducBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/dapperUtilityCoinVault)\n profile.addWallet(Profile.Wallet( name:\"DUC\", receiver:ducReceiver, balance: ducBalanceCap, accept: Type\u003c@DapperUtilityCoin.Vault\u003e(), tags: [\"duc\", \"dapperUtilityCoin\",\"dapper\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"FUT\") {\n var futReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver)\n var futBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowUtilityTokenBalance)\n if !futReceiver.check() {\n // Create a new Forwarder resource for FUT and store it in the new account's storage\n let futForwarder \u003c- TokenForwarding.createNewForwarder(recipient: dapper.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver))\n account.storage.save(\u003c-futForwarder, to: /storage/flowUtilityTokenReceiver)\n futReceiver = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/flowUtilityTokenReceiver)\n account.capabilities.publish(futReceiver, at: /public/flowUtilityTokenReceiver)\n }\n if !futBalanceCap.check() {\n futBalanceCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/flowUtilityTokenVault)\n account.capabilities.publish(futBalanceCap, at: /public/flowUtilityTokenBalance)\n }\n profile.addWallet(Profile.Wallet( name:\"FUT\", receiver:futReceiver, balance:futBalanceCap, accept: Type\u003c@FlowUtilityToken.Vault\u003e(), tags: [\"fut\", \"flowUtilityToken\",\"dapper\"]))\n updated=true\n }\n\n profile.emitCreatedEvent()\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let dosSaleType= Type\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e()\n let dosSalePublicPath=FindMarket.getPublicPath(dosSaleType, name: tenant.name)\n let dosSaleStoragePath= FindMarket.getStoragePath(dosSaleType, name:tenant.name)\n let dosSaleCap= account.capabilities.get\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSalePublicPath)\n if !dosSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferSoft.createEmptySaleItemCollection(tenantCapability), to: dosSaleStoragePath)\n let dosSaleCap= account.capabilities.storage.issue\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSaleStoragePath)\n account.capabilities.publish(dosSaleCap, at: dosSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" }, "deleteFindThoughts": { "spec": { @@ -3897,7 +3976,7 @@ "removeLinks" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\n\ntransaction(name:String, description: String, avatar: String, tags:[String], allowStoringFollowers: Bool, linkTitles : {String: String}, linkTypes: {String:String}, linkUrls : {String:String}, removeLinks : [String]) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check() {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n }\n\n execute{\n self.profile.setName(name)\n self.profile.setDescription(description)\n self.profile.setAvatar(avatar)\n self.profile.setTags(tags)\n\n for link in removeLinks {\n self.profile.removeLink(link)\n }\n\n for titleName in linkTitles.keys {\n let title=linkTitles[titleName]!\n let url = linkUrls[titleName]!\n let type = linkTypes[titleName]!\n\n self.profile.addLinkWithName(name:titleName, link: Profile.Link(title: title, type: type, url: url))\n }\n self.profile.emitUpdatedEvent()\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\ntransaction(name:String, description: String, avatar: String, tags:[String], allowStoringFollowers: Bool, linkTitles : {String: String}, linkTypes: {String:String}, linkUrls : {String:String}, removeLinks : [String]) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n\n execute{\n self.profile.setName(name)\n self.profile.setDescription(description)\n self.profile.setAvatar(avatar)\n self.profile.setTags(tags)\n\n for link in removeLinks {\n self.profile.removeLink(link)\n }\n\n for titleName in linkTitles.keys {\n let title=linkTitles[titleName]!\n let url = linkUrls[titleName]!\n let type = linkTypes[titleName]!\n\n self.profile.addLinkWithName(name:titleName, link: Profile.Link(title: title, type: type, url: url))\n }\n self.profile.emitUpdatedEvent()\n }\n}" }, "editProfileDapper": { "spec": { @@ -3935,7 +4014,7 @@ "follows" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\n\n// map of {User in string (find name or address) : [tag]}\ntransaction(follows:{String : [String]}) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check(){\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check(){\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n\n }\n\n execute{\n for key in follows.keys {\n let user = FIND.resolve(key) ?? panic(key.concat(\" cannot be resolved. It is either an invalid .find name or address\"))\n let tags = follows[key]!\n self.profile.follow(user, tags: tags)\n }\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\n\n// map of {User in string (find name or address) : [tag]}\ntransaction(follows:{String : [String]}) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check(){\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n }\n\n execute{\n for key in follows.keys {\n let user = FIND.resolve(key) ?? panic(key.concat(\" cannot be resolved. It is either an invalid .find name or address\"))\n let tags = follows[key]!\n self.profile.follow(user, tags: tags)\n }\n }\n}" }, "fulfillLeaseMarketAuctionSoft": { "spec": { @@ -4277,6 +4356,13 @@ }, "code": "import TokenForwarding from 0x51ea0e37c27a1f1a\nimport FungibleToken from 0x9a0766d93b6608b7\n\n\ntransaction() {\n prepare(account: auth(BorrowValue) \u0026Account) {\n account.unlink(/public/dapperUtilityCoinReceiver)\n account.link\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver,target: /storage/dapperUtilityCoinVault)\n }\n}" }, + "linkForLeaseMarket": { + "spec": { + "parameters": {}, + "order": [] + }, + "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\n\ntransaction() {\n prepare(account: auth (StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" + }, "listLeaseForAuctionSoft": { "spec": { "parameters": { @@ -4300,7 +4386,7 @@ "auctionValidUntil" ] }, - "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, PublishCapability,Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" + "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, PublishCapability,Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" }, "listLeaseForAuctionSoftDapper": { "spec": { @@ -4327,6 +4413,23 @@ }, "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" }, + "listLeaseForSale": { + "spec": { + "parameters": { + "directSellPrice": "UFix64", + "ftAliasOrIdentifier": "String", + "leaseName": "String", + "validUntil": "UFix64?" + }, + "order": [ + "leaseName", + "ftAliasOrIdentifier", + "directSellPrice", + "validUntil" + ] + }, + "code": "import FindMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindMarketSale from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" + }, "listLeaseForSaleDapper": { "spec": { "parameters": { @@ -4342,7 +4445,7 @@ "validUntil" ] }, - "code": "import FindMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindMarketSale from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" + "code": "import FindMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindMarketSale from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" }, "listNFTForAuctionEscrowed": { "spec": { @@ -4639,15 +4742,15 @@ "register": { "spec": { "parameters": { - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xe223d8a629e49c68\nimport FIND from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\n\ntransaction(name: String, amount: UFix64) {\n\n let vaultRef : auth(FungibleToken.Withdraw) \u0026FUSD.Vault?\n let leases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection?\n let price : UFix64\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n\n self.price=FIND.calculateCost(name)\n log(\"The cost for registering this name is \".concat(self.price.toString()))\n self.vaultRef = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n self.leases=account.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath)\n }\n\n pre{\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.leases != nil : \"Could not borrow reference to find lease collection\"\n self.price == amount : \"Calculated cost : \".concat(self.price.toString()).concat(\" does not match expected cost : \").concat(amount.toString())\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.price) as! @FUSD.Vault\n\n //TODO: entitlements\n self.leases!.register(name: name, vault: \u003c- payVault)\n }\n}" + "code": "import FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\n\ntransaction(name: String, maxAmount: UFix64) {\n\n let vaultRef : auth(FungibleToken.Withdraw) \u0026FlowToken.Vault?\n let leases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection?\n let cost : UFix64\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n\n self.vaultRef = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.leases=account.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath)\n\n self.cost = FIND.calculateCostInFlow(name)\n\n }\n\n\n pre{\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.leases != nil : \"Could not borrow reference to find lease collection\"\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.cost.toString()).concat(\" total balance is \").concat(self.vaultRef!.balance.toString())\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n self.leases!.register(name: name, vault: \u003c- payVault)\n }\n}" }, "registerFindPackMetadata": { "spec": { @@ -4842,15 +4945,15 @@ "renewName": { "spec": { "parameters": { - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xe223d8a629e49c68\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\n\ntransaction(name: String, amount: UFix64) {\n\n let price : UFix64\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FUSD.Vault? \n let finLeases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection? \n\n prepare(acct: auth(BorrowValue) \u0026Account) {\n self.price=FIND.calculateCost(name)\n self.vaultRef = acct.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n self.finLeases= acct.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n }\n\n pre{\n self.price == amount : \"expected renew cost : \".concat(self.price.toString()).concat(\" is not the same as calculated renew cost : \").concat(amount.toString())\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.finLeases != nil : \"Could not borrow reference to find lease collection\"\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.price) \n let finToken= self.finLeases!.borrow(name)\n finToken.extendLease(\u003c- payVault)\n }\n}" + "code": "import FlowToken from 0x7e60df042a9c0868\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\n\ntransaction(name: String, maxAmount: UFix64) {\n\n let cost : UFix64\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FlowToken.Vault? \n let finLeases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection? \n\n prepare(acct: auth(BorrowValue) \u0026Account) {\n self.cost=FIND.calculateCostInFlow(name)\n self.vaultRef = acct.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.finLeases= acct.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n }\n\n\n pre{\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.finLeases != nil : \"Could not borrow reference to find lease collection\"\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.vaultRef!.balance.toString().concat(\" total balance is \").concat(self.vaultRef!.balance.toString()))\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n let finToken= self.finLeases!.borrow(name)\n finToken.extendLease(\u003c- payVault)\n }\n}" }, "retractOfferLeaseMarketDirectOfferSoft": { "spec": { @@ -5150,6 +5253,21 @@ }, "code": "import FindMarket from 0x35717efbbce11c74\nimport DapperUtilityCoin from 0x82ec283f88a62e65\nimport FlowUtilityToken from 0x82ec283f88a62e65\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FungibleTokenSwitchboard from 0x9a0766d93b6608b7\n\ntransaction(nftName: String, nftType: String, cut: UFix64){\n prepare(account: auth(BorrowValue) \u0026Account){\n\n let defaultRules : [FindMarket.TenantRule] = [\n FindMarket.TenantRule(\n name: \"Dapper\",\n types:[Type\u003c@DapperUtilityCoin.Vault\u003e(), Type\u003c@FlowUtilityToken.Vault\u003e()],\n ruleType: \"ft\",\n allow:true\n ),\n FindMarket.TenantRule(\n name: \"Soft\",\n types:[Type\u003c@FindLeaseMarketSale.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketAuctionSoft.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItem\u003e()\n ],\n ruleType: \"listing\",\n allow:true\n )\n ]\n\n defaultRules.append(\n FindMarket.TenantRule(\n name: nftName,\n types:[CompositeType(nftType)!],\n ruleType: \"nft\",\n allow:true\n )\n )\n\n var royalty : MetadataViews.Royalty? = nil\n if cut != 0.0 {\n royalty = MetadataViews.Royalty(\n receiver: account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FungibleTokenSwitchboard.ReceiverPublicPath)!,\n cut: cut,\n description: \"tenant\"\n )\n }\n\n let saleItem = FindMarket.TenantSaleItem(\n name: \"Dapper\".concat(nftName).concat(\"Soft\"),\n cut: royalty,\n rules: defaultRules,\n status: \"active\"\n )\n\n let clientRef = account.storage.borrow\u003cauth(FindMarket.TenantClientOwner) \u0026FindMarket.TenantClient\u003e(from: FindMarket.TenantClientStoragePath) ?? panic(\"Cannot borrow Tenant Client Reference.\")\n clientRef.setMarketOption(saleItem: saleItem)\n }\n}" }, + "tenantsetLeaseOptionMarket": { + "spec": { + "parameters": { + "cut": "UFix64", + "nftName": "String", + "nftType": "String" + }, + "order": [ + "nftName", + "nftType", + "cut" + ] + }, + "code": "import FindMarket from 0x35717efbbce11c74\nimport FlowToken from 0x7e60df042a9c0868\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FungibleTokenSwitchboard from 0x9a0766d93b6608b7\n\ntransaction(nftName: String, nftType: String, cut: UFix64){\n prepare(account: auth(BorrowValue) \u0026Account){\n\n let defaultRules : [FindMarket.TenantRule] = [\n FindMarket.TenantRule(\n name: \"Flow\",\n types:[Type\u003c@FlowToken.Vault\u003e()],\n ruleType: \"ft\",\n allow:true\n ),\n FindMarket.TenantRule(\n name: \"Soft\",\n types:[Type\u003c@FindLeaseMarketSale.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketAuctionSoft.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItem\u003e()\n ],\n ruleType: \"listing\",\n allow:true\n )\n ]\n\n defaultRules.append(\n FindMarket.TenantRule(\n name: nftName,\n types:[CompositeType(nftType)!],\n ruleType: \"nft\",\n allow:true\n )\n )\n\n var royalty : MetadataViews.Royalty? = nil\n if cut != 0.0 {\n royalty = MetadataViews.Royalty(\n receiver: account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FungibleTokenSwitchboard.ReceiverPublicPath),\n cut: cut,\n description: \"tenant\"\n )\n }\n\n let saleItem = FindMarket.TenantSaleItem(\n name: \"Flow\".concat(nftName).concat(\"Soft\"),\n cut: royalty,\n rules: defaultRules,\n status: \"active\"\n )\n\n let clientRef = account.storage.borrow\u003cauth(FindMarket.TenantClientOwner) \u0026FindMarket.TenantClient\u003e(from: FindMarket.TenantClientStoragePath) ?? panic(\"Cannot borrow Tenant Client Reference.\")\n clientRef.setMarketOption(saleItem: saleItem)\n }\n}" + }, "tenantsetMarketOption": { "spec": { "parameters": { @@ -5408,7 +5526,7 @@ "user" ] }, - "code": "import FIND from 0x35717efbbce11c74\nimport FUSD from 0xe223d8a629e49c68\nimport FindMarket from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\n\naccess(all) struct FINDReport{\n\n access(all) let leases: [FIND.LeaseInformation]\n access(all) let leasesBids: [FIND.BidInfo]\n access(all) let itemsForSale: {String : FindMarket.SaleItemCollectionReport}\n access(all) let marketBids: {String : FindMarket.BidItemCollectionReport}\n\n init(\n bids: [FIND.BidInfo],\n leases : [FIND.LeaseInformation],\n leasesBids: [FIND.BidInfo],\n itemsForSale: {String : FindMarket.SaleItemCollectionReport},\n marketBids: {String : FindMarket.BidItemCollectionReport},\n ) {\n\n self.leases=leases\n self.leasesBids=leasesBids\n self.itemsForSale=itemsForSale\n self.marketBids=marketBids\n }\n}\n\n\naccess(all) fun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n let bidCap=account.capabilities.borrow\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n let leaseCap = account.capabilities.borrow\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n\n let leases = leaseCap?.getLeaseInformation() ?? []\n let oldLeaseBid = bidCap?.getBids() ?? []\n\n let find= FindMarket.getFindTenantAddress()\n var items : {String : FindMarket.SaleItemCollectionReport} = FindMarket.getSaleItemReport(tenant:find, address: address, getNFTInfo:true)\n var marketBids : {String : FindMarket.BidItemCollectionReport} = FindMarket.getBidsReport(tenant:find, address: address, getNFTInfo:true)\n\n return FINDReport(\n bids: oldLeaseBid,\n leases: leases,\n leasesBids: oldLeaseBid,\n itemsForSale: items,\n marketBids: marketBids,\n )\n}" + "code": "import FIND from 0x35717efbbce11c74\nimport FUSD from 0xe223d8a629e49c68\nimport FindMarket from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\n\naccess(all) struct FINDReport{\n\n access(all) let leases: [FIND.LeaseInformation]\n access(all) let leasesBids: [FIND.BidInfo]\n access(all) let itemsForSale: {String : FindMarket.SaleItemCollectionReport}\n access(all) let marketBids: {String : FindMarket.BidItemCollectionReport}\n\n init(\n bids: [FIND.BidInfo],\n leases : [FIND.LeaseInformation],\n leasesBids: [FIND.BidInfo],\n itemsForSale: {String : FindMarket.SaleItemCollectionReport},\n marketBids: {String : FindMarket.BidItemCollectionReport},\n ) {\n\n self.leases=leases\n self.leasesBids=leasesBids\n self.itemsForSale=itemsForSale\n self.marketBids=marketBids\n }\n}\n\n\naccess(all) fun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n let leaseCap = account.capabilities.borrow\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n let leases = leaseCap?.getLeaseInformation() ?? []\n let find= FindMarket.getFindTenantAddress()\n var items : {String : FindMarket.SaleItemCollectionReport} = FindMarket.getSaleItemReport(tenant:find, address: address, getNFTInfo:true)\n var marketBids : {String : FindMarket.BidItemCollectionReport} = FindMarket.getBidsReport(tenant:find, address: address, getNFTInfo:true)\n\n return FINDReport(\n bids: [],\n leases: leases,\n leasesBids: [],\n itemsForSale: items,\n marketBids: marketBids,\n )\n}" }, "getFindNameMarket": { "spec": { @@ -5430,7 +5548,7 @@ "user" ] }, - "code": "import FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindRelatedAccounts from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FindUtils from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\nimport LostAndFound from 0xbe4635353f55bbd4\n\naccess(all) \nstruct FINDReport{\n access(all) let isDapper: Bool\n access(all) let profile:Profile.UserReport?\n access(all) let privateMode: Bool\n access(all) let activatedAccount: Bool\n access(all) let hasLostAndFoundItem: Bool\n access(all) let accounts : [AccountInformation]?\n //not sure\n access(all) let readyForWearables : Bool?\n\n init(profile: Profile.UserReport?,\n privateMode: Bool,\n activatedAccount: Bool,\n isDapper: Bool,\n hasLostAndFoundItem: Bool,\n accounts: [AccountInformation]?,\n readyForWearables: Bool?\n) {\n\n self.hasLostAndFoundItem=hasLostAndFoundItem\n self.profile=profile\n self.privateMode=privateMode\n self.activatedAccount=activatedAccount\n self.isDapper=isDapper\n self.accounts=accounts\n self.readyForWearables=readyForWearables\n}\n}\n\naccess(all) struct AccountInformation {\n access(all) let name: String\n access(all) let address: String\n access(all) let network: String\n access(all) let trusted: Bool\n access(all) let node: String\n\n init(name: String, address: String, network: String, trusted: Bool, node: String) {\n self.name = name\n self.address = address\n self.network = network\n self.trusted = trusted\n self.node = node\n }\n}\n\n\naccess(all) \nfun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n //why not auth account here?\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n var isDapper=false\n if let receiver =account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver) {\n isDapper=receiver.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n if let duc = account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver){\n isDapper = duc.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n isDapper = false\n }\n }\n\n let profile=account.capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n var profileReport = profile?.asReport()\n if profileReport != nil \u0026\u0026 profileReport!.findName != FIND.reverseLookup(address) {\n profileReport = Profile.UserReport(\n findName: \"\",\n address: profileReport!.address,\n name: profileReport!.name,\n gender: profileReport!.gender,\n description: profileReport!.description,\n tags: profileReport!.tags,\n avatar: profileReport!.avatar,\n links: profileReport!.links,\n wallets: profileReport!.wallets,\n following: profileReport!.following,\n followers: profileReport!.followers,\n allowStoringFollowers: profileReport!.allowStoringFollowers,\n createdAt: profileReport!.createdAt\n )\n }\n\n let discordID = \"\"//EmeraldIdentity.getDiscordFromAccount(account: address) ?? \"\"\n\n let emeraldIDAccounts : {String : Address} = {}\n //emeraldIDAccounts[\"blocto\"] = EmeraldIdentity.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"lilico\"] = EmeraldIdentityLilico.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"dapper\"] = EmeraldIdentityDapper.getAccountFromDiscord(discordID: discordID)\n\n let accounts : [AccountInformation] = []\n for wallet in [\"blocto\", \"lilico\", \"dapper\"] {\n if let w = emeraldIDAccounts[wallet] {\n if w == address {\n continue\n }\n\n accounts.append(\n AccountInformation(\n name: wallet,\n address: w.toString(),\n network: \"Flow\",\n trusted: true,\n node: \"EmeraldID\")\n )\n }\n }\n\n if let allAcctsCap = FindRelatedAccounts.getCapability(address) {\n let allAcctsRef = allAcctsCap.borrow()!\n let allAccts = allAcctsRef.getAllRelatedAccountInfo()\n for acct in allAccts.values {\n // We only verify flow accounts that are mutually linked\n var trusted = false\n if acct.address != nil {\n if acct.address! == address {\n continue\n }\n trusted = allAcctsRef.linked(name: acct.name, network: acct.network, address: acct.address!)\n }\n accounts.append(AccountInformation(\n name: acct.name,\n address: acct.stringAddress,\n network: acct.network,\n trusted: trusted,\n node: \"FindRelatedAccounts\")\n )\n }\n }\n\n var readyForWearables = false\n var hasLostAndFoundItem : Bool = false\n\n for t in LostAndFound.getRedeemableTypes(address) {\n if t.isSubtype(of: Type\u003c@{NonFungibleToken.NFT}\u003e()) {\n hasLostAndFoundItem = true\n break\n }\n }\n\n return FINDReport(\n profile: profileReport,\n privateMode: profile?.isPrivateModeEnabled() ?? false,\n activatedAccount: true,\n isDapper:isDapper,\n hasLostAndFoundItem: hasLostAndFoundItem,\n accounts: accounts,\n readyForWearables: readyForWearables,\n )\n }" + "code": "import FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindRelatedAccounts from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FindUtils from 0x35717efbbce11c74\nimport Clock from 0x35717efbbce11c74\nimport LostAndFound from 0xbe4635353f55bbd4\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\naccess(all) struct FINDReport{\n access(all) let isDapper: Bool\n access(all) let profile:Profile.UserReport?\n access(all) let privateMode: Bool\n access(all) let activatedAccount: Bool\n access(all) let hasLostAndFoundItem: Bool\n access(all) let isReadyForNameOffer: Bool\n access(all) let accounts : [AccountInformation]?\n //not sure\n access(all) let readyForWearables : Bool?\n\n init(profile: Profile.UserReport?,\n privateMode: Bool,\n activatedAccount: Bool,\n isDapper: Bool,\n hasLostAndFoundItem: Bool,\n accounts: [AccountInformation]?,\n readyForWearables: Bool?,\n isReadyForNameOffer: Bool) {\n\n self.hasLostAndFoundItem=hasLostAndFoundItem\n self.profile=profile\n self.privateMode=privateMode\n self.activatedAccount=activatedAccount\n self.isDapper=isDapper\n self.accounts=accounts\n self.readyForWearables=readyForWearables\n self.isReadyForNameOffer=isReadyForNameOffer\n }\n}\n\naccess(all) struct AccountInformation {\n access(all) let name: String\n access(all) let address: String\n access(all) let network: String\n access(all) let trusted: Bool\n access(all) let node: String\n\n init(name: String, address: String, network: String, trusted: Bool, node: String) {\n self.name = name\n self.address = address\n self.network = network\n self.trusted = trusted\n self.node = node\n }\n}\n\n\naccess(all) \nfun main(user: String) : FINDReport? {\n\n let maybeAddress=FIND.resolve(user)\n if maybeAddress == nil{\n return nil\n }\n\n let address=maybeAddress!\n\n //why not auth account here?\n let account=getAccount(address)\n if account.balance == 0.0 {\n return nil\n }\n\n\n var isDapper=false\n if let receiver =account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver) {\n isDapper=receiver.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n if let duc = account.capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver){\n isDapper = duc.isInstance(Type\u003c@TokenForwarding.Forwarder\u003e())\n } else {\n isDapper = false\n }\n }\n\n let profile=account.capabilities.borrow\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n var profileReport = profile?.asReport()\n if profileReport != nil \u0026\u0026 profileReport!.findName != FIND.reverseLookup(address) {\n profileReport = Profile.UserReport(\n findName: \"\",\n address: profileReport!.address,\n name: profileReport!.name,\n gender: profileReport!.gender,\n description: profileReport!.description,\n tags: profileReport!.tags,\n avatar: profileReport!.avatar,\n links: profileReport!.links,\n wallets: profileReport!.wallets,\n following: profileReport!.following,\n followers: profileReport!.followers,\n allowStoringFollowers: profileReport!.allowStoringFollowers,\n createdAt: profileReport!.createdAt\n )\n }\n\n let discordID = \"\"//EmeraldIdentity.getDiscordFromAccount(account: address) ?? \"\"\n\n let emeraldIDAccounts : {String : Address} = {}\n //emeraldIDAccounts[\"blocto\"] = EmeraldIdentity.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"lilico\"] = EmeraldIdentityLilico.getAccountFromDiscord(discordID: discordID)\n // emeraldIDAccounts[\"dapper\"] = EmeraldIdentityDapper.getAccountFromDiscord(discordID: discordID)\n\n let accounts : [AccountInformation] = []\n for wallet in [\"blocto\", \"lilico\", \"dapper\"] {\n if let w = emeraldIDAccounts[wallet] {\n if w == address {\n continue\n }\n\n accounts.append(\n AccountInformation(\n name: wallet,\n address: w.toString(),\n network: \"Flow\",\n trusted: true,\n node: \"EmeraldID\")\n )\n }\n }\n\n if let allAcctsCap = FindRelatedAccounts.getCapability(address) {\n let allAcctsRef = allAcctsCap.borrow()!\n let allAccts = allAcctsRef.getAllRelatedAccountInfo()\n for acct in allAccts.values {\n // We only verify flow accounts that are mutually linked\n var trusted = false\n if acct.address != nil {\n if acct.address! == address {\n continue\n }\n trusted = allAcctsRef.linked(name: acct.name, network: acct.network, address: acct.address!)\n }\n accounts.append(AccountInformation(\n name: acct.name,\n address: acct.stringAddress,\n network: acct.network,\n trusted: trusted,\n node: \"FindRelatedAccounts\")\n )\n }\n }\n\n var readyForWearables = false\n var hasLostAndFoundItem : Bool = false\n\n for t in LostAndFound.getRedeemableTypes(address) {\n if t.isSubtype(of: Type\u003c@{NonFungibleToken.NFT}\u003e()) {\n hasLostAndFoundItem = true\n break\n }\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n let readyForLeaseOffer =leaseDOSSaleItemCap.check()\n\n return FINDReport(\n profile: profileReport,\n privateMode: profile?.isPrivateModeEnabled() ?? false,\n activatedAccount: true,\n isDapper:isDapper,\n hasLostAndFoundItem: hasLostAndFoundItem,\n accounts: accounts,\n readyForWearables: readyForWearables,\n isReadyForNameOffer: readyForLeaseOffer\n )\n }" }, "getFindThoughts": { "spec": { @@ -5927,6 +6045,21 @@ } }, "transactions": { + "RegisterFlow": { + "spec": { + "parameters": { + "amountInMax": "UFix64", + "exactAmountOut": "UFix64", + "name": "String" + }, + "order": [ + "name", + "amountInMax", + "exactAmountOut" + ] + }, + "code": "import FiatToken from 0xa983fecbed621163\nimport FlowToken from 0x7e60df042a9c0868\nimport FungibleToken from 0x9a0766d93b6608b7\nimport SwapRouter from 0x2f8af5ed05bbde0d\nimport FIND from 0x35717efbbce11c74\n\ntransaction(\n name: String, \n amountInMax: UFix64,\n exactAmountOut: UFix64,\n) {\n\n let payVault : @FiatToken.Vault\n let leases : \u0026FIND.LeaseCollection?\n let price : UFix64\n\n\n prepare(userAccount: AuthAccount) {\n\n self.price=FIND.calculateCost(name)\n self.leases=userAccount.borrow\u003c\u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath)\n\n let deadline = getCurrentBlock().timestamp + 1000.0\n let tokenInVaultPath = /storage/flowTokenVault\n let tokenOutReceiverPath = /public/USDCVaultReceiver\n\n let inVaultRef = userAccount.borrow\u003c\u0026FungibleToken.Vault\u003e(from: tokenInVaultPath) ?? panic(\"Could not borrow reference to the owner's in FT.Vault\")\n\n let path = [ \"A.7e60df042a9c0868.FlowToken\", \"A.a983fecbed621163.FiatToken\" ]\n\n let vaultInMax \u003c- inVaultRef.withdraw(amount: amountInMax)\n let swapResVault \u003c- SwapRouter.swapTokensForExactTokens(\n vaultInMax: \u003c-vaultInMax,\n exactAmountOut: exactAmountOut,\n tokenKeyPath: path,\n deadline: deadline\n )\n\n let tempVault \u003c- swapResVault.removeFirst() \n self.payVault \u003c- tempVault as! @FiatToken.Vault\n let vaultInLeft \u003c- swapResVault.removeLast()\n destroy swapResVault\n inVaultRef.deposit(from: \u003c-vaultInLeft)\n }\n\n pre{\n self.leases != nil : \"Could not borrow reference to find lease collection\"\n self.price == exactAmountOut : \"Calculated cost : \".concat(self.price.toString()).concat(\" does not match expected cost : \").concat(exactAmountOut.toString())\n }\n\n execute{\n self.leases!.registerUSDC(name: name, vault: \u003c- self.payVault)\n }\n\n}" + }, "acceptDirectOfferSoft": { "spec": { "parameters": { @@ -5958,7 +6091,7 @@ "leaseName" ] }, - "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n let marketOption = FindMarket.getMarketOptionFromType(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n let item = FindLeaseMarket.assertOperationValid(tenant: marketplace, name: leaseName, marketOption: marketOption)\n let ref = account.capabilities.storage.get\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath) ?? panic(\"Cannot borrow reference to find lease collection. Account : \".concat(account.address.toString()))\n self.pointer= FindLeaseMarket.AuthLeasePointer(ref: ref, name: leaseName)\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n}" + "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n}" }, "acceptLeaseDirectOfferSoftDapper": { "spec": { @@ -5969,7 +6102,7 @@ "leaseName" ] }, - "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n\n}" + "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FindViews from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\n\ntransaction(leaseName: String) {\n\n let market : auth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n\n prepare(account: auth(Storage, IssueStorageCapabilityController) \u0026Account) {\n\n let marketplace = FindMarket.getFindTenantAddress()\n let tenant=FindMarket.getTenant(marketplace)\n let storagePath=tenant.getStoragePath(Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e())\n self.market = account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Seller) \u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(from: storagePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n\n\n }\n\n execute {\n self.market.acceptOffer(self.pointer)\n }\n\n}" }, "acceptMultipleDirectOfferSoft": { "spec": { @@ -6088,7 +6221,7 @@ "validUntil" ] }, - "code": "import Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, validUntil: UFix64?) {\n\n let bidsReference: \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection?\n let ftVaultType: Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n\n let resolveAddress = FIND.resolve(leaseName)\n if resolveAddress == nil {panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))}\n let address = resolveAddress!\n\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n self.ftVaultType = ft.type\n\n let walletReference = account.storage.borrow\u003c\u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n assert(walletReference.balance \u003e amount , message: \"Bidder has to have enough balance in wallet\")\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)!\n let leaseDOSBidType= Type\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e()\n let leaseDOSBidPublicPath=leaseTenant.getPublicPath(leaseDOSBidType)\n let leaseDOSBidStoragePath= leaseTenant.getStoragePath(leaseDOSBidType)\n let leaseDOSBidCap= account.getCapability\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath)\n if !leaseDOSBidCap.check() {\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptyMarketBidCollection(receiver:receiverCap, tenantCapability:leaseTenantCapability), to: leaseDOSBidStoragePath)\n account.link\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath, target: leaseDOSBidStoragePath)\n }\n\n self.bidsReference= account.storage.borrow\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(from: leaseDOSBidStoragePath)\n\n }\n\n pre {\n self.bidsReference != nil : \"This account does not have a bid collection\"\n }\n\n execute {\n self.bidsReference!.bid(name:leaseName, amount: amount, vaultType: self.ftVaultType, validUntil: validUntil, saleItemExtraField: {}, bidExtraField: {})\n }\n}" + "code": "import Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, validUntil: UFix64?) {\n\n let bidsReference: auth(FindLeaseMarketDirectOfferSoft.Buyer) \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection?\n let ftVaultType: Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n\n let resolveAddress = FIND.resolve(leaseName)\n if resolveAddress == nil {panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))}\n let address = resolveAddress!\n\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n self.ftVaultType = ft.type\n\n let walletReference = account.storage.borrow\u003c\u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n assert(walletReference.balance \u003e amount , message: \"Bidder has to have enough balance in wallet\")\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let leaseDOSBidType= Type\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e()\n let leaseDOSBidPublicPath=leaseTenant.getPublicPath(leaseDOSBidType)\n let leaseDOSBidStoragePath= leaseTenant.getStoragePath(leaseDOSBidType)\n let leaseDOSBidCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidPublicPath)\n if !leaseDOSBidCap.check() {\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptyMarketBidCollection(receiver:receiverCap, tenantCapability:leaseTenantCapability), to: leaseDOSBidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(leaseDOSBidStoragePath)\n account.capabilities.publish(cap, at: leaseDOSBidPublicPath)\n }\n\n self.bidsReference= account.storage.borrow\u003cauth(FindLeaseMarketDirectOfferSoft.Buyer) \u0026FindLeaseMarketDirectOfferSoft.MarketBidCollection\u003e(from: leaseDOSBidStoragePath)\n\n }\n\n pre {\n self.bidsReference != nil : \"This account does not have a bid collection\"\n }\n\n execute {\n self.bidsReference!.bid(name:leaseName, amount: amount, vaultType: self.ftVaultType, validUntil: validUntil, saleItemExtraField: {}, bidExtraField: {})\n }\n}" }, "bidLeaseMarketDirectOfferSoftDapper": { "spec": { @@ -6310,16 +6443,16 @@ "spec": { "parameters": { "addon": "String", - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", "addon", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xe223d8a629e49c68\nimport FIND from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\n\n\ntransaction(name: String, addon:String, amount:UFix64) {\n\n let leases : \u0026FIND.LeaseCollection?\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FUSD.Vault? \n\n prepare(account: auth (BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n self.leases= account.storage.borrow\u003c\u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n self.vaultRef = account.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n\n }\n\n pre{\n self.leases != nil : \"Could not borrow reference to the leases collection\"\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n }\n\n execute {\n let vault \u003c- self.vaultRef!.withdraw(amount: amount) as! @FUSD.Vault\n self.leases!.buyAddon(name: name, addon: addon, vault: \u003c- vault)\n }\n}" + "code": "import FIND from 0x35717efbbce11c74\nimport FlowToken from 0x7e60df042a9c0868\nimport FungibleToken from 0x9a0766d93b6608b7\n\n\ntransaction(name: String, addon:String, maxAmount:UFix64) {\n\n let leases : \u0026FIND.LeaseCollection?\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FlowToken.Vault? \n let cost: UFix64\n\n prepare(account: auth (BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n self.leases= account.storage.borrow\u003c\u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n self.vaultRef = account.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.cost=FIND.calculateAddonCostInFlow(addon)\n }\n\n pre{\n self.leases != nil : \"Could not borrow reference to the leases collection\"\n self.vaultRef != nil : \"Could not borrow reference to the flow token vault!\"\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.vaultRef!.balance.toString().concat(\" total balance is \").concat(self.vaultRef!.balance.toString()))\n }\n\n execute {\n let vault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n self.leases!.buyAddon(name: name, addon: addon, vault: \u003c- vault)\n }\n}" }, "buyAddonDapper": { "spec": { @@ -6355,6 +6488,19 @@ }, "code": "import FindPack from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FlowToken from 0x7e60df042a9c0868\nimport FUSD from 0xe223d8a629e49c68\nimport Profile from 0x35717efbbce11c74\n\ntransaction(packTypeName: String, packTypeId:UInt64, numberOfPacks:UInt64, totalAmount: UFix64) {\n let packs: \u0026FindPack.Collection\n\n let userPacks: Capability\u003c\u0026FindPack.Collection\u003e\n let salePrice: UFix64\n let packsLeft: UInt64\n\n let userFlowTokenVault: auth(FungibleToken.Withdraw) \u0026FlowToken.Vault\n\n let paymentVault: @{FungibleToken.Vault}\n let balanceBeforeTransfer:UFix64\n\n prepare(account: auth (StorageCapabilities, SaveValue,PublishCapability, BorrowValue, FungibleToken.Withdraw) \u0026Account) {\n\n\n let col = account.storage.borrow\u003c\u0026FindPack.Collection\u003e(from: FindPack.CollectionStoragePath)\n if col == nil {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType:Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:account.address.toString(), createdAt: \"find\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n\n profile.addWallet(fusdWallet)\n\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n profile.addWallet(flowWallet)\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n }\n\n self.userPacks=account.capabilities.get\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionPublicPath)\n self.packs=FindPack.getPacksCollection(packTypeName: packTypeName, packTypeId:packTypeId)\n\n self.salePrice= FindPack.getCurrentPrice(packTypeName: packTypeName, packTypeId:packTypeId, user:account.address) ?? panic (\"Cannot buy the pack now\") \n self.packsLeft= UInt64(self.packs.getPacksLeft())\n\n\n self.userFlowTokenVault = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault) ?? panic(\"Cannot borrow FlowToken vault from account storage\")\n self.balanceBeforeTransfer = self.userFlowTokenVault.balance\n\n if self.balanceBeforeTransfer \u003c totalAmount {\n panic(\"Your account does not have enough funds has \".concat(self.balanceBeforeTransfer.toString()).concat(\" needs \").concat(totalAmount.toString()))\n }\n self.paymentVault \u003c- self.userFlowTokenVault.withdraw(amount: totalAmount)\n }\n\n pre {\n self.salePrice * UFix64(numberOfPacks) == totalAmount: \"unexpected sending amount\"\n self.packsLeft \u003e= numberOfPacks : \"Rats! there are no packs left\"\n self.userPacks.check() : \"User need a receiver to put the pack in\"\n }\n\n execute {\n var counter = numberOfPacks\n while counter \u003e 0 {\n let purchasingVault \u003c- self.paymentVault.withdraw(amount: self.salePrice)\n self.packs.buy(packTypeName: packTypeName, typeId:packTypeId, vault: \u003c- purchasingVault, collectionCapability: self.userPacks)\n counter = counter - 1\n }\n if self.paymentVault.balance != 0.0 {\n panic(\"paymentVault balance is non-zero after paying\")\n }\n destroy self.paymentVault\n }\n\n}" }, + "buyLeaseForSale": { + "spec": { + "parameters": { + "amount": "UFix64", + "leaseName": "String" + }, + "order": [ + "leaseName", + "amount" + ] + }, + "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, amount: UFix64) {\n\n let buyer : Address\n let walletReference : auth(FungibleToken.Withdraw) \u0026{FungibleToken.Vault}\n\n let saleItemCollection: \u0026{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic}\n\n prepare(account: auth(BorrowValue, SaveValue, IssueStorageCapabilityController) \u0026Account) {\n\n let profile=account.storage.borrow\u003c\u0026Profile.User\u003e(from: Profile.storagePath) ?? panic(\"You do not have a profile set up, initialize the user first\")\n\n let address = FIND.resolve(leaseName) ?? panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))\n\n if address == nil {\n panic(\"The address input is not a valid name nor address. Input : \".concat(leaseName))\n }\n\n let leaseMarketplace = FindMarket.getTenantAddress(\"find\") ?? panic(\"Cannot find find tenant\")\n let saleItemsCap= FindLeaseMarketSale.getSaleItemCapability(marketplace: leaseMarketplace, user:address) ?? panic(\"cannot find sale item cap for find\")\n\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=FindMarket.getPublicPath(leaseSaleItemType, name: \"find\")\n let leaseStoragePath= FindMarket.getStoragePath(leaseSaleItemType, name:\"find\")\n var leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check(){\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath)\n leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n }\n\n self.saleItemCollection = saleItemsCap.borrow()!\n let item = self.saleItemCollection.borrowSaleItem(leaseName)\n\n let ft = FTRegistry.getFTInfoByTypeIdentifier(item.getFtType().identifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(item.getFtType().identifier))\n\n\n self.walletReference = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026{FungibleToken.Vault}\u003e(from: ft.vaultPath) ?? panic(\"No suitable wallet linked for this account\")\n self.buyer = account.address\n }\n\n pre {\n self.walletReference.balance \u003e amount : \"Your wallet does not have enough funds to pay for this item\"\n }\n\n execute {\n let vault \u003c- self.walletReference.withdraw(amount: amount)\n self.saleItemCollection.buy(name:leaseName, vault: \u003c- vault, to: self.buyer)\n }\n}" + }, "buyLeaseForSaleDapper": { "spec": { "parameters": { @@ -6575,7 +6721,7 @@ "name" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport FUSD from 0xe223d8a629e49c68\nimport FiatToken from 0xa983fecbed621163\nimport FlowToken from 0x7e60df042a9c0868\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport FindPack from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferEscrow from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\n//import \"FindThoughts\"\n\ntransaction(name: String) {\n prepare(account: auth (Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n //if we do not have a profile it might be stored under a different address so we will just remove it\n let profileCapFirst = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if profileCapFirst.check() {\n return \n }\n\n //the code below has some dead code for this specific transaction, but it is hard to maintain otherwise\n //SYNC with register\n //Add exising FUSD or create a new one and add it\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n let usdcCap = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n if !usdcCap.check() {\n account.storage.save( \u003c-FiatToken.createEmptyVault(), to: FiatToken.VaultStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FiatToken.Vault\u003e(FiatToken.VaultStoragePath)\n account.capabilities.publish(cap, at: FiatToken.VaultUUIDPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultReceiverPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultBalancePubPath)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check(){\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026Dandy.Collection\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(cap, at: Dandy.CollectionPublicPath)\n }\n\n let findPackCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(FindPack.CollectionPublicPath)\n if !findPackCap.check() {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType: Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026Profile.User\u003e(Profile.publicPath)\n if !profileCap.check(){\n let newProfile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-newProfile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n if !profile.hasWallet(\"Flow\") {\n let flowWallet=Profile.Wallet( name:\"Flow\", receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver), balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance), accept: Type\u003c@FlowToken.Vault\u003e(), tags: [\"flow\"])\n\n profile.addWallet(flowWallet)\n updated=true\n }\n if !profile.hasWallet(\"FUSD\") {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance)\n profile.addWallet(Profile.Wallet( name:\"FUSD\", receiver:fr, balance:fb, accept: Type\u003c@FUSD.Vault\u003e(), tags: [\"fusd\", \"stablecoin\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"USDC\") {\n\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(FiatToken.VaultBalancePubPath) \n profile.addWallet(Profile.Wallet( name:\"USDC\", receiver:fr, balance:fb, accept: Type\u003c@FiatToken.Vault\u003e(), tags: [\"usdc\", \"stablecoin\"]))\n updated=true\n }\n\n /*\n //If find name not set and we have a profile set it.\n if profile.getFindName() == \"\" {\n if let findName = FIND.reverseLookup(account.address) {\n profile.setFindName(findName)\n // If name is set, it will emit Updated Event, there is no need to emit another update event below. \n updated=false\n }\n }\n */\n\n if created {\n profile.emitCreatedEvent()\n } else if updated {\n profile.emitUpdatedEvent()\n }\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let doeSaleType= Type\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e()\n let doeSalePublicPath=FindMarket.getPublicPath(doeSaleType, name: tenant.name)\n let doeSaleStoragePath= FindMarket.getStoragePath(doeSaleType, name:tenant.name)\n let doeSaleCap= account.capabilities.get\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic}\u003e(doeSalePublicPath) \n if !doeSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferEscrow.createEmptySaleItemCollection(tenantCapability), to: doeSaleStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic, FindMarket.SaleItemCollectionPublic}\u003e(doeSaleStoragePath)\n account.capabilities.publish(cap, at: doeSalePublicPath)\n }\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport FUSD from 0xe223d8a629e49c68\nimport FiatToken from 0xa983fecbed621163\nimport FlowToken from 0x7e60df042a9c0868\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport FindPack from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferEscrow from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\n\ntransaction(name: String) {\n prepare(account: auth (Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n //if we do not have a profile it might be stored under a different address so we will just remove it\n let profileCapFirst = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if profileCapFirst.check() {\n return \n }\n\n //the code below has some dead code for this specific transaction, but it is hard to maintain otherwise\n //SYNC with register\n //Add exising FUSD or create a new one and add it\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n let usdcCap = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n if !usdcCap.check() {\n account.storage.save( \u003c-FiatToken.createEmptyVault(), to: FiatToken.VaultStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FiatToken.Vault\u003e(FiatToken.VaultStoragePath)\n account.capabilities.publish(cap, at: FiatToken.VaultUUIDPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultReceiverPubPath)\n account.capabilities.publish(cap, at: FiatToken.VaultBalancePubPath)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026Dandy.Collection\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(cap, at: Dandy.CollectionPublicPath)\n }\n\n let findPackCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(FindPack.CollectionPublicPath)\n if !findPackCap.check() {\n account.storage.save( \u003c- FindPack.createEmptyCollection(nftType: Type\u003c@FindPack.NFT\u003e()), to: FindPack.CollectionStoragePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026FindPack.Collection\u003e(FindPack.CollectionStoragePath)\n account.capabilities.publish(cap, at: FindPack.CollectionPublicPath)\n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026Profile.User\u003e(Profile.publicPath)\n if !profileCap.check(){\n let newProfile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-newProfile, to: Profile.storagePath)\n\n let cap = account.capabilities.storage.issue\u003c\u0026Profile.User\u003e(Profile.storagePath)\n account.capabilities.publish(cap, at: Profile.publicPath)\n account.capabilities.publish(cap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n if !profile.hasWallet(\"Flow\") {\n let flowWallet=Profile.Wallet( name:\"Flow\", receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver), balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance), accept: Type\u003c@FlowToken.Vault\u003e(), tags: [\"flow\"])\n\n profile.addWallet(flowWallet)\n updated=true\n }\n if !profile.hasWallet(\"FUSD\") {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance)\n profile.addWallet(Profile.Wallet( name:\"FUSD\", receiver:fr, balance:fb, accept: Type\u003c@FUSD.Vault\u003e(), tags: [\"fusd\", \"stablecoin\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"USDC\") {\n\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FiatToken.VaultReceiverPubPath)\n let fb =account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(FiatToken.VaultBalancePubPath) \n profile.addWallet(Profile.Wallet( name:\"USDC\", receiver:fr, balance:fb, accept: Type\u003c@FiatToken.Vault\u003e(), tags: [\"usdc\", \"stablecoin\"]))\n updated=true\n }\n\n /*\n //If find name not set and we have a profile set it.\n if profile.getFindName() == \"\" {\n if let findName = FIND.reverseLookup(account.address) {\n profile.setFindName(findName)\n // If name is set, it will emit Updated Event, there is no need to emit another update event below. \n updated=false\n }\n }\n */\n\n if created {\n profile.emitCreatedEvent()\n } else if updated {\n profile.emitUpdatedEvent()\n }\n\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let doeSaleType= Type\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e()\n let doeSalePublicPath=FindMarket.getPublicPath(doeSaleType, name: tenant.name)\n let doeSaleStoragePath= FindMarket.getStoragePath(doeSaleType, name:tenant.name)\n let doeSaleCap= account.capabilities.get\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic}\u003e(doeSalePublicPath) \n if !doeSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferEscrow.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferEscrow.createEmptySaleItemCollection(tenantCapability), to: doeSaleStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026{FindMarketDirectOfferEscrow.SaleItemCollectionPublic, FindMarket.SaleItemCollectionPublic}\u003e(doeSaleStoragePath)\n account.capabilities.publish(cap, at: doeSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n\n }\n}" }, "createProfileDapper": { "spec": { @@ -6586,7 +6732,7 @@ "name" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferSoft from 0x35717efbbce11c74\nimport DapperUtilityCoin from 0x82ec283f88a62e65\nimport FlowUtilityToken from 0x82ec283f88a62e65\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FindViews from 0x35717efbbce11c74\n\ntransaction(name: String) {\n prepare(account: auth(Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let leaseCollectionCap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(leaseCollectionCap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save\u003c@{NonFungibleToken.Collection}\u003e(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let dandyCollectionCap = account.capabilities.storage.issue\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(dandyCollectionCap, at: Dandy.CollectionPublicPath) \n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n let profileCap = account.capabilities.storage.issue\u003c\u0026{Profile.Public}\u003e(Profile.storagePath)\n account.capabilities.publish(profileCap, at: Profile.publicPath)\n let receiverCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.storagePath)\n account.capabilities.publish(receiverCap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n let dapper=getAccount(FindViews.getDapperAddress())\n\n if !profile.hasWallet(\"DUC\") {\n var ducReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver)\n var ducBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/dapperUtilityCoinVault)\n profile.addWallet(Profile.Wallet( name:\"DUC\", receiver:ducReceiver, balance: ducBalanceCap, accept: Type\u003c@DapperUtilityCoin.Vault\u003e(), tags: [\"duc\", \"dapperUtilityCoin\",\"dapper\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"FUT\") {\n var futReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver)\n var futBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowUtilityTokenBalance)\n if !futReceiver.check() {\n // Create a new Forwarder resource for FUT and store it in the new account's storage\n let futForwarder \u003c- TokenForwarding.createNewForwarder(recipient: dapper.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver))\n account.storage.save(\u003c-futForwarder, to: /storage/flowUtilityTokenReceiver)\n futReceiver = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/flowUtilityTokenReceiver)\n account.capabilities.publish(futReceiver, at: /public/flowUtilityTokenReceiver)\n }\n if !futBalanceCap.check() {\n futBalanceCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/flowUtilityTokenVault)\n account.capabilities.publish(futBalanceCap, at: /public/flowUtilityTokenBalance)\n }\n profile.addWallet(Profile.Wallet( name:\"FUT\", receiver:futReceiver, balance:futBalanceCap, accept: Type\u003c@FlowUtilityToken.Vault\u003e(), tags: [\"fut\", \"flowUtilityToken\",\"dapper\"]))\n updated=true\n }\n\n profile.emitCreatedEvent()\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let dosSaleType= Type\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e()\n let dosSalePublicPath=FindMarket.getPublicPath(dosSaleType, name: tenant.name)\n let dosSaleStoragePath= FindMarket.getStoragePath(dosSaleType, name:tenant.name)\n let dosSaleCap= account.capabilities.get\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSalePublicPath)\n if !dosSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferSoft.createEmptySaleItemCollection(tenantCapability), to: dosSaleStoragePath)\n let dosSaleCap= account.capabilities.storage.issue\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSaleStoragePath)\n account.capabilities.publish(dosSaleCap, at: dosSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport NonFungibleToken from 0x631e88ae7f1d7c20\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FIND from 0x35717efbbce11c74\nimport Dandy from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindMarketDirectOfferSoft from 0x35717efbbce11c74\nimport DapperUtilityCoin from 0x82ec283f88a62e65\nimport FlowUtilityToken from 0x82ec283f88a62e65\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport TokenForwarding from 0x51ea0e37c27a1f1a\nimport FindViews from 0x35717efbbce11c74\n\ntransaction(name: String) {\n prepare(account: auth(Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n\n let leaseCollection = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let leaseCollectionCap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(leaseCollectionCap, at: FIND.LeasePublicPath)\n }\n\n let dandyCap= account.capabilities.get\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionPublicPath)\n if !dandyCap.check() {\n account.storage.save\u003c@{NonFungibleToken.Collection}\u003e(\u003c- Dandy.createEmptyCollection(nftType:Type\u003c@Dandy.NFT\u003e()), to: Dandy.CollectionStoragePath)\n let dandyCollectionCap = account.capabilities.storage.issue\u003c\u0026{NonFungibleToken.Collection}\u003e(Dandy.CollectionStoragePath)\n account.capabilities.publish(dandyCollectionCap, at: Dandy.CollectionPublicPath) \n }\n\n var created=false\n var updated=false\n let profileCap = account.capabilities.get\u003c\u0026{Profile.Public}\u003e(Profile.publicPath)\n if !profileCap.check() {\n let profile \u003c-Profile.createUser(name:name, createdAt: \"find\")\n account.storage.save(\u003c-profile, to: Profile.storagePath)\n let profileCap = account.capabilities.storage.issue\u003c\u0026{Profile.Public}\u003e(Profile.storagePath)\n account.capabilities.publish(profileCap, at: Profile.publicPath)\n let receiverCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.storagePath)\n account.capabilities.publish(receiverCap, at: Profile.publicReceiverPath)\n created=true\n }\n\n let profile=account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from: Profile.storagePath)!\n\n let dapper=getAccount(FindViews.getDapperAddress())\n\n if !profile.hasWallet(\"DUC\") {\n var ducReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver)\n var ducBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/dapperUtilityCoinVault)\n profile.addWallet(Profile.Wallet( name:\"DUC\", receiver:ducReceiver, balance: ducBalanceCap, accept: Type\u003c@DapperUtilityCoin.Vault\u003e(), tags: [\"duc\", \"dapperUtilityCoin\",\"dapper\"]))\n updated=true\n }\n\n if !profile.hasWallet(\"FUT\") {\n var futReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver)\n var futBalanceCap = account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowUtilityTokenBalance)\n if !futReceiver.check() {\n // Create a new Forwarder resource for FUT and store it in the new account's storage\n let futForwarder \u003c- TokenForwarding.createNewForwarder(recipient: dapper.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowUtilityTokenReceiver))\n account.storage.save(\u003c-futForwarder, to: /storage/flowUtilityTokenReceiver)\n futReceiver = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/flowUtilityTokenReceiver)\n account.capabilities.publish(futReceiver, at: /public/flowUtilityTokenReceiver)\n }\n if !futBalanceCap.check() {\n futBalanceCap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/flowUtilityTokenVault)\n account.capabilities.publish(futBalanceCap, at: /public/flowUtilityTokenBalance)\n }\n profile.addWallet(Profile.Wallet( name:\"FUT\", receiver:futReceiver, balance:futBalanceCap, accept: Type\u003c@FlowUtilityToken.Vault\u003e(), tags: [\"fut\", \"flowUtilityToken\",\"dapper\"]))\n updated=true\n }\n\n profile.emitCreatedEvent()\n\n let receiverCap=account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(Profile.publicReceiverPath)\n let tenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n\n let tenant = tenantCapability.borrow()!\n\n let dosSaleType= Type\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e()\n let dosSalePublicPath=FindMarket.getPublicPath(dosSaleType, name: tenant.name)\n let dosSaleStoragePath= FindMarket.getStoragePath(dosSaleType, name:tenant.name)\n let dosSaleCap= account.capabilities.get\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSalePublicPath)\n if !dosSaleCap.check() {\n account.storage.save\u003c@FindMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindMarketDirectOfferSoft.createEmptySaleItemCollection(tenantCapability), to: dosSaleStoragePath)\n let dosSaleCap= account.capabilities.storage.issue\u003c\u0026FindMarketDirectOfferSoft.SaleItemCollection\u003e(dosSaleStoragePath)\n account.capabilities.publish(dosSaleCap, at: dosSalePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" }, "deleteFindThoughts": { "spec": { @@ -6695,7 +6841,7 @@ "removeLinks" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\n\ntransaction(name:String, description: String, avatar: String, tags:[String], allowStoringFollowers: Bool, linkTitles : {String: String}, linkTypes: {String:String}, linkUrls : {String:String}, removeLinks : [String]) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check() {\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n }\n\n execute{\n self.profile.setName(name)\n self.profile.setDescription(description)\n self.profile.setAvatar(avatar)\n self.profile.setTags(tags)\n\n for link in removeLinks {\n self.profile.removeLink(link)\n }\n\n for titleName in linkTitles.keys {\n let title=linkTitles[titleName]!\n let url = linkUrls[titleName]!\n let type = linkTypes[titleName]!\n\n self.profile.addLinkWithName(name:titleName, link: Profile.Link(title: title, type: type, url: url))\n }\n self.profile.emitUpdatedEvent()\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\n\ntransaction(name:String, description: String, avatar: String, tags:[String], allowStoringFollowers: Bool, linkTitles : {String: String}, linkTypes: {String:String}, linkUrls : {String:String}, removeLinks : [String]) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check() {\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\", \n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n\n execute{\n self.profile.setName(name)\n self.profile.setDescription(description)\n self.profile.setAvatar(avatar)\n self.profile.setTags(tags)\n\n for link in removeLinks {\n self.profile.removeLink(link)\n }\n\n for titleName in linkTitles.keys {\n let title=linkTitles[titleName]!\n let url = linkUrls[titleName]!\n let type = linkTypes[titleName]!\n\n self.profile.addLinkWithName(name:titleName, link: Profile.Link(title: title, type: type, url: url))\n }\n self.profile.emitUpdatedEvent()\n }\n}" }, "editProfileDapper": { "spec": { @@ -6733,7 +6879,7 @@ "follows" ] }, - "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\n\n// map of {User in string (find name or address) : [tag]}\ntransaction(follows:{String : [String]}) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check(){\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n let bidCollection = account.capabilities.get\u003c\u0026FIND.BidCollection\u003e(FIND.BidPublicPath)\n if !bidCollection.check(){\n let fr = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n let lc = account.capabilities.get\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeasePublicPath)\n account.storage.save(\u003c- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.BidCollection\u003e(FIND.BidStoragePath)\n account.capabilities.publish(cap, at: FIND.BidPublicPath)\n }\n\n }\n\n execute{\n for key in follows.keys {\n let user = FIND.resolve(key) ?? panic(key.concat(\" cannot be resolved. It is either an invalid .find name or address\"))\n let tags = follows[key]!\n self.profile.follow(user, tags: tags)\n }\n }\n}" + "code": "import FungibleToken from 0x9a0766d93b6608b7\nimport FUSD from 0xe223d8a629e49c68\nimport FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport Profile from 0x35717efbbce11c74\n\n// map of {User in string (find name or address) : [tag]}\ntransaction(follows:{String : [String]}) {\n\n let profile : auth(Profile.Admin) \u0026Profile.User\n\n prepare(account: auth(BorrowValue, SaveValue, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n self.profile =account.storage.borrow\u003cauth(Profile.Admin) \u0026Profile.User\u003e(from:Profile.storagePath) ?? panic(\"Cannot borrow reference to profile\")\n\n\n let fusdReceiver = account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver)\n if !fusdReceiver.check(){\n let fusd \u003c- FUSD.createEmptyVault(vaultType: Type\u003c@FUSD.Vault\u003e())\n account.storage.save(\u003c- fusd, to: /storage/fusdVault)\n var cap = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Receiver}\u003e(/storage/fusdVault)\n account.capabilities.publish(cap, at: /public/fusdReceiver)\n let capb = account.capabilities.storage.issue\u003c\u0026{FungibleToken.Vault}\u003e(/storage/fusdVault)\n account.capabilities.publish(capb, at: /public/fusdBalance)\n }\n\n var hasFusdWallet=false\n var hasFlowWallet=false\n let wallets=self.profile.getWallets()\n for wallet in wallets {\n if wallet.name==\"FUSD\" {\n hasFusdWallet=true\n }\n\n if wallet.name ==\"Flow\" {\n hasFlowWallet=true\n }\n }\n\n if !hasFlowWallet {\n let flowWallet=Profile.Wallet(\n name:\"Flow\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/flowTokenBalance),\n accept: Type\u003c@FlowToken.Vault\u003e(),\n tags: [\"flow\"]\n )\n self.profile.addWallet(flowWallet)\n }\n\n if !hasFusdWallet {\n let fusdWallet=Profile.Wallet(\n name:\"FUSD\",\n receiver:account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(/public/fusdReceiver),\n balance:account.capabilities.get\u003c\u0026{FungibleToken.Vault}\u003e(/public/fusdBalance),\n accept: Type\u003c@FUSD.Vault\u003e(),\n tags: [\"fusd\", \"stablecoin\"]\n )\n self.profile.addWallet(fusdWallet)\n }\n\n let leaseCollection = account.capabilities.get\u003c\u0026{FIND.LeaseCollectionPublic}\u003e(FIND.LeasePublicPath)\n if !leaseCollection.check() {\n account.storage.save(\u003c- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath)\n let cap = account.capabilities.storage.issue\u003c\u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath)\n account.capabilities.publish(cap, at: FIND.LeasePublicPath)\n }\n\n }\n\n execute{\n for key in follows.keys {\n let user = FIND.resolve(key) ?? panic(key.concat(\" cannot be resolved. It is either an invalid .find name or address\"))\n let tags = follows[key]!\n self.profile.follow(user, tags: tags)\n }\n }\n}" }, "fulfillLeaseMarketAuctionSoft": { "spec": { @@ -7075,6 +7221,13 @@ }, "code": "import TokenForwarding from 0x51ea0e37c27a1f1a\nimport FungibleToken from 0x9a0766d93b6608b7\n\n\ntransaction() {\n prepare(account: auth(BorrowValue) \u0026Account) {\n account.unlink(/public/dapperUtilityCoinReceiver)\n account.link\u003c\u0026{FungibleToken.Receiver}\u003e(/public/dapperUtilityCoinReceiver,target: /storage/dapperUtilityCoinVault)\n }\n}" }, + "linkForLeaseMarket": { + "spec": { + "parameters": {}, + "order": [] + }, + "code": "import FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport FindMarket from 0x35717efbbce11c74\n\ntransaction() {\n prepare(account: auth (StorageCapabilities, SaveValue,PublishCapability, BorrowValue) \u0026Account) {\n let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseDOSSaleItemType= Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e()\n let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType)\n let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType)\n let leaseDOSSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSPublicPath)\n if !leaseDOSSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath)\n let leaseDOSSaleItemCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketDirectOfferSoft.SaleItemCollection\u003e(leaseDOSStoragePath)\n account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath)\n }\n }\n}" + }, "listLeaseForAuctionSoft": { "spec": { "parameters": { @@ -7098,7 +7251,7 @@ "auctionValidUntil" ] }, - "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, PublishCapability,Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" + "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier:String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, PublishCapability,Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)!\n\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" }, "listLeaseForAuctionSoftDapper": { "spec": { @@ -7125,6 +7278,23 @@ }, "code": "import FindMarket from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, price:UFix64, auctionReservePrice: UFix64, auctionDuration: UFix64, auctionExtensionOnLateBid: UFix64, minimumBidIncrement: UFix64, auctionValidUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection?\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, Storage, IssueStorageCapabilityController) \u0026Account) {\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseASSaleItemType= Type\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e()\n let leaseASPublicPath=leaseTenant.getPublicPath(leaseASSaleItemType)\n let leaseASStoragePath= leaseTenant.getStoragePath(leaseASSaleItemType)\n let leaseASSaleItemCap= account.capabilities.get\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASPublicPath)\n if !leaseASSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(\u003c- FindLeaseMarketAuctionSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseASStoragePath)\n let saleColCap = account.capabilities.storage.issue\u003c\u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(leaseASStoragePath)\n account.capabilities.publish(saleColCap, at: leaseASPublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketAuctionSoft.Seller) \u0026FindLeaseMarketAuctionSoft.SaleItemCollection\u003e(from: leaseASStoragePath)\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n self.vaultType= ft.type\n }\n\n pre{\n // Ben : panic on some unreasonable inputs in trxn\n minimumBidIncrement \u003e 0.0 :\"Minimum bid increment should be larger than 0.\"\n (auctionReservePrice - auctionReservePrice) % minimumBidIncrement == 0.0 : \"Acution ReservePrice should be in step of minimum bid increment.\"\n auctionDuration \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n auctionExtensionOnLateBid \u003e 0.0 : \"Auction Duration should be greater than 0.\"\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems!.listForAuction(pointer: self.pointer, vaultType: self.vaultType, auctionStartPrice: price, auctionReservePrice: auctionReservePrice, auctionDuration: auctionDuration, auctionExtensionOnLateBid: auctionExtensionOnLateBid, minimumBidIncrement: minimumBidIncrement, auctionValidUntil: auctionValidUntil, saleItemExtraField: {})\n\n }\n}" }, + "listLeaseForSale": { + "spec": { + "parameters": { + "directSellPrice": "UFix64", + "ftAliasOrIdentifier": "String", + "leaseName": "String", + "validUntil": "UFix64?" + }, + "order": [ + "leaseName", + "ftAliasOrIdentifier", + "directSellPrice", + "validUntil" + ] + }, + "code": "import FindMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindMarketSale from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"ProviderFlow\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" + }, "listLeaseForSaleDapper": { "spec": { "parameters": { @@ -7140,7 +7310,7 @@ "validUntil" ] }, - "code": "import FindMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindMarketSale from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n\n // Get supported NFT and FT Information from Registries from input alias\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" + "code": "import FindMarket from 0x35717efbbce11c74\nimport FIND from 0x35717efbbce11c74\nimport FTRegistry from 0x35717efbbce11c74\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarket from 0x35717efbbce11c74\nimport FindMarketSale from 0x35717efbbce11c74\n\ntransaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) {\n\n let saleItems : auth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\n let pointer : FindLeaseMarket.AuthLeasePointer\n let vaultType : Type\n\n prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) \u0026Account) {\n\n // Get the salesItemRef from tenant\n let leaseMarketplace = FindMarket.getFindTenantAddress()\n let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)!\n let leaseTenant = leaseTenantCapability.borrow()!\n\n let leaseSaleItemType= Type\u003c@FindLeaseMarketSale.SaleItemCollection\u003e()\n let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType)\n let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType)\n let leaseSaleItemCap= account.capabilities.get\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leasePublicPath)\n if !leaseSaleItemCap.check() {\n //The link here has to be a capability not a tenant, because it can change.\n account.storage.save\u003c@FindLeaseMarketSale.SaleItemCollection\u003e(\u003c- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) \n let leaseSaleItemCap= account.capabilities.storage.issue\u003c\u0026{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}\u003e(leaseStoragePath)\n account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath)\n }\n\n self.saleItems= account.storage.borrow\u003cauth(FindLeaseMarketSale.Seller) \u0026FindLeaseMarketSale.SaleItemCollection\u003e(from: leaseStoragePath)!\n let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic(\"This FT is not supported by the Find Market yet. Type : \".concat(ftAliasOrIdentifier))\n self.vaultType= ft.type\n\n let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:\"/\")[1]\n let providerIdentifier = storagePathIdentifer.concat(\"Provider\")\n let providerStoragePath = StoragePath(identifier: providerIdentifier)!\n\n var existingProvider= account.storage.copy\u003cCapability\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e\u003e(from: providerStoragePath) \n if existingProvider==nil {\n existingProvider=account.capabilities.storage.issue\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(FIND.LeaseStoragePath) \n account.storage.save(existingProvider!, to: providerStoragePath)\n }\n var cap = existingProvider!\n self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName)\n }\n\n pre{\n self.saleItems != nil : \"Cannot borrow reference to saleItem\"\n }\n\n execute{\n self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {})\n }\n\n}" }, "listNFTForAuctionEscrowed": { "spec": { @@ -7418,15 +7588,15 @@ "register": { "spec": { "parameters": { - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xe223d8a629e49c68\nimport FIND from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\n\ntransaction(name: String, amount: UFix64) {\n\n let vaultRef : auth(FungibleToken.Withdraw) \u0026FUSD.Vault?\n let leases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection?\n let price : UFix64\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n\n self.price=FIND.calculateCost(name)\n log(\"The cost for registering this name is \".concat(self.price.toString()))\n self.vaultRef = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n self.leases=account.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath)\n }\n\n pre{\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.leases != nil : \"Could not borrow reference to find lease collection\"\n self.price == amount : \"Calculated cost : \".concat(self.price.toString()).concat(\" does not match expected cost : \").concat(amount.toString())\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.price) as! @FUSD.Vault\n\n //TODO: entitlements\n self.leases!.register(name: name, vault: \u003c- payVault)\n }\n}" + "code": "import FlowToken from 0x7e60df042a9c0868\nimport FIND from 0x35717efbbce11c74\nimport FungibleToken from 0x9a0766d93b6608b7\n\ntransaction(name: String, maxAmount: UFix64) {\n\n let vaultRef : auth(FungibleToken.Withdraw) \u0026FlowToken.Vault?\n let leases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection?\n let cost : UFix64\n\n prepare(account: auth(BorrowValue) \u0026Account) {\n\n self.vaultRef = account.storage.borrow\u003cauth(FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.leases=account.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from: FIND.LeaseStoragePath)\n\n self.cost = FIND.calculateCostInFlow(name)\n\n }\n\n\n pre{\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.leases != nil : \"Could not borrow reference to find lease collection\"\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.cost.toString()).concat(\" total balance is \").concat(self.vaultRef!.balance.toString())\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n self.leases!.register(name: name, vault: \u003c- payVault)\n }\n}" }, "registerDapper": { "spec": { @@ -7636,15 +7806,15 @@ "renewName": { "spec": { "parameters": { - "amount": "UFix64", + "maxAmount": "UFix64", "name": "String" }, "order": [ "name", - "amount" + "maxAmount" ] }, - "code": "import FUSD from 0xe223d8a629e49c68\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\n\ntransaction(name: String, amount: UFix64) {\n\n let price : UFix64\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FUSD.Vault? \n let finLeases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection? \n\n prepare(acct: auth(BorrowValue) \u0026Account) {\n self.price=FIND.calculateCost(name)\n self.vaultRef = acct.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FUSD.Vault\u003e(from: /storage/fusdVault)\n self.finLeases= acct.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n }\n\n pre{\n self.price == amount : \"expected renew cost : \".concat(self.price.toString()).concat(\" is not the same as calculated renew cost : \").concat(amount.toString())\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.finLeases != nil : \"Could not borrow reference to find lease collection\"\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.price) \n let finToken= self.finLeases!.borrow(name)\n finToken.extendLease(\u003c- payVault)\n }\n}" + "code": "import FlowToken from 0x7e60df042a9c0868\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FIND from 0x35717efbbce11c74\n\ntransaction(name: String, maxAmount: UFix64) {\n\n let cost : UFix64\n let vaultRef : auth (FungibleToken.Withdraw) \u0026FlowToken.Vault? \n let finLeases : auth(FIND.LeaseOwner) \u0026FIND.LeaseCollection? \n\n prepare(acct: auth(BorrowValue) \u0026Account) {\n self.cost=FIND.calculateCostInFlow(name)\n self.vaultRef = acct.storage.borrow\u003cauth (FungibleToken.Withdraw) \u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)\n self.finLeases= acct.storage.borrow\u003cauth(FIND.LeaseOwner) \u0026FIND.LeaseCollection\u003e(from:FIND.LeaseStoragePath)\n }\n\n\n pre{\n self.vaultRef != nil : \"Could not borrow reference to the fusdVault!\"\n self.finLeases != nil : \"Could not borrow reference to find lease collection\"\n self.cost \u003c= maxAmount : \"You have not sent in enough max flow, the cost is \".concat(self.cost.toString())\n self.vaultRef!.balance \u003e self.cost : \"Balance of vault is not high enough \".concat(self.vaultRef!.balance.toString().concat(\" total balance is \").concat(self.vaultRef!.balance.toString()))\n }\n\n execute{\n let payVault \u003c- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault\n let finToken= self.finLeases!.borrow(name)\n finToken.extendLease(\u003c- payVault)\n }\n}" }, "renewNameDapper": { "spec": { @@ -7959,6 +8129,21 @@ }, "code": "import FindMarket from 0x35717efbbce11c74\nimport DapperUtilityCoin from 0x82ec283f88a62e65\nimport FlowUtilityToken from 0x82ec283f88a62e65\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FungibleTokenSwitchboard from 0x9a0766d93b6608b7\n\ntransaction(nftName: String, nftType: String, cut: UFix64){\n prepare(account: auth(BorrowValue) \u0026Account){\n\n let defaultRules : [FindMarket.TenantRule] = [\n FindMarket.TenantRule(\n name: \"Dapper\",\n types:[Type\u003c@DapperUtilityCoin.Vault\u003e(), Type\u003c@FlowUtilityToken.Vault\u003e()],\n ruleType: \"ft\",\n allow:true\n ),\n FindMarket.TenantRule(\n name: \"Soft\",\n types:[Type\u003c@FindLeaseMarketSale.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketAuctionSoft.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItem\u003e()\n ],\n ruleType: \"listing\",\n allow:true\n )\n ]\n\n defaultRules.append(\n FindMarket.TenantRule(\n name: nftName,\n types:[CompositeType(nftType)!],\n ruleType: \"nft\",\n allow:true\n )\n )\n\n var royalty : MetadataViews.Royalty? = nil\n if cut != 0.0 {\n royalty = MetadataViews.Royalty(\n receiver: account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FungibleTokenSwitchboard.ReceiverPublicPath)!,\n cut: cut,\n description: \"tenant\"\n )\n }\n\n let saleItem = FindMarket.TenantSaleItem(\n name: \"Dapper\".concat(nftName).concat(\"Soft\"),\n cut: royalty,\n rules: defaultRules,\n status: \"active\"\n )\n\n let clientRef = account.storage.borrow\u003cauth(FindMarket.TenantClientOwner) \u0026FindMarket.TenantClient\u003e(from: FindMarket.TenantClientStoragePath) ?? panic(\"Cannot borrow Tenant Client Reference.\")\n clientRef.setMarketOption(saleItem: saleItem)\n }\n}" }, + "tenantsetLeaseOptionMarket": { + "spec": { + "parameters": { + "cut": "UFix64", + "nftName": "String", + "nftType": "String" + }, + "order": [ + "nftName", + "nftType", + "cut" + ] + }, + "code": "import FindMarket from 0x35717efbbce11c74\nimport FlowToken from 0x7e60df042a9c0868\nimport FindLeaseMarketSale from 0x35717efbbce11c74\nimport FindLeaseMarketAuctionSoft from 0x35717efbbce11c74\nimport FindLeaseMarketDirectOfferSoft from 0x35717efbbce11c74\nimport MetadataViews from 0x631e88ae7f1d7c20\nimport FungibleToken from 0x9a0766d93b6608b7\nimport FungibleTokenSwitchboard from 0x9a0766d93b6608b7\n\ntransaction(nftName: String, nftType: String, cut: UFix64){\n prepare(account: auth(BorrowValue) \u0026Account){\n\n let defaultRules : [FindMarket.TenantRule] = [\n FindMarket.TenantRule(\n name: \"Flow\",\n types:[Type\u003c@FlowToken.Vault\u003e()],\n ruleType: \"ft\",\n allow:true\n ),\n FindMarket.TenantRule(\n name: \"Soft\",\n types:[Type\u003c@FindLeaseMarketSale.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketAuctionSoft.SaleItem\u003e(),\n Type\u003c@FindLeaseMarketDirectOfferSoft.SaleItem\u003e()\n ],\n ruleType: \"listing\",\n allow:true\n )\n ]\n\n defaultRules.append(\n FindMarket.TenantRule(\n name: nftName,\n types:[CompositeType(nftType)!],\n ruleType: \"nft\",\n allow:true\n )\n )\n\n var royalty : MetadataViews.Royalty? = nil\n if cut != 0.0 {\n royalty = MetadataViews.Royalty(\n receiver: account.capabilities.get\u003c\u0026{FungibleToken.Receiver}\u003e(FungibleTokenSwitchboard.ReceiverPublicPath),\n cut: cut,\n description: \"tenant\"\n )\n }\n\n let saleItem = FindMarket.TenantSaleItem(\n name: \"Flow\".concat(nftName).concat(\"Soft\"),\n cut: royalty,\n rules: defaultRules,\n status: \"active\"\n )\n\n let clientRef = account.storage.borrow\u003cauth(FindMarket.TenantClientOwner) \u0026FindMarket.TenantClient\u003e(from: FindMarket.TenantClientStoragePath) ?? panic(\"Cannot borrow Tenant Client Reference.\")\n clientRef.setMarketOption(saleItem: saleItem)\n }\n}" + }, "tenantsetMarketOption": { "spec": { "parameters": { diff --git a/lib/package.json b/lib/package.json index 9d74e9dc..13d19984 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,23 +1,23 @@ { - "name": "@findonflow/find-flow-contracts-1.0", - "version": "1.0.8", - "description": "Cadence transactions and scripts to work with https://find.xyz for cadence 1.0", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/findonflow/find.git" - }, - "keywords": [ - "cadence", - "client" - ], - "author": "Find on Flow LLP", - "license": "MIT", - "bugs": { - "url": "https://github.com/findonflow/find/issues" - }, - "homepage": "https://github.com/findonflow/find#readme" + "name": "@findonflow/find-flow-contracts-1.0", + "version": "1.1.1", + "description": "Cadence transactions and scripts to work with https://find.xyz for cadence 1.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/findonflow/find.git" + }, + "keywords": [ + "cadence", + "client" + ], + "author": "Find on Flow LLP", + "license": "MIT", + "bugs": { + "url": "https://github.com/findonflow/find/issues" + }, + "homepage": "https://github.com/findonflow/find#readme" } diff --git a/market_sale_test.go b/market_sale_test.go index 968172be..be96a961 100644 --- a/market_sale_test.go +++ b/market_sale_test.go @@ -128,13 +128,6 @@ func TestMarketSale(t *testing.T) { ). AssertFailure(t, "Incorrect balance sent in vault. Expected 10.00000000 got 5.00000000") }) - - ot.Run(t, "Should be able to list it in Flow but not FUSD.", func(t *testing.T) { - listingTx("listNFTForSale", - WithArg("ftAliasOrIdentifier", "FUSD"), - ).AssertFailure(t, "Nothing matches") - }) - ot.Run(t, "Should be able cancel all listing", func(t *testing.T) { otu.listNFTForSale("user1", dandyIds[0], price) otu.listNFTForSale("user1", dandyIds[1], price) @@ -371,45 +364,6 @@ func TestMarketSale(t *testing.T) { ) }) - ot.Run(t, "Royalties should be sent to residual account if royalty receiver is not working", func(t *testing.T) { - otu.registerUser("user3") - otu.sendDandy("user3", "user1", id) - - otu.O.Tx("devtenantsetMarketOptionAll", - WithSigner("find"), - WithArg("nftName", "Dandy"), - WithArg("nftType", dandyIdentifier), - WithArg("cut", 0.0), - ). - AssertSuccess(otu.T) - - listingTx("listNFTForSale", - WithSigner("user3"), - WithArg("id", id), - WithArg("ftAliasOrIdentifier", "FUSD"), - ).AssertSuccess(t) - - otu.destroyFUSDVault("user1") - - otu.O.Tx("buyNFTForSale", - WithSigner("user2"), - WithArg("user", "user3"), - WithArg("id", id), - WithArg("amount", price), - ). - AssertSuccess(t). - AssertEvent(t, - "FindMarket.RoyaltyCouldNotBePaid", - map[string]interface{}{ - "address": otu.O.Address("user1"), - "amount": 0.5, - "findName": "user1", - "residualAddress": otu.O.Address("residual"), - "royaltyName": "creator", - }, - ) - }) - //TODO: have no idea why this does not work tbh /* ot.Run(t, "Should not be able to list soul bound items", func(t *testing.T) { diff --git a/scripts/getFindMarket.cdc b/scripts/getFindMarket.cdc index 03a69ce6..096d5133 100644 --- a/scripts/getFindMarket.cdc +++ b/scripts/getFindMarket.cdc @@ -41,20 +41,16 @@ access(all) fun main(user: String) : FINDReport? { } - let bidCap=account.capabilities.borrow<&FIND.BidCollection>(FIND.BidPublicPath) let leaseCap = account.capabilities.borrow<&FIND.LeaseCollection>(FIND.LeasePublicPath) - let leases = leaseCap?.getLeaseInformation() ?? [] - let oldLeaseBid = bidCap?.getBids() ?? [] - let find= FindMarket.getFindTenantAddress() var items : {String : FindMarket.SaleItemCollectionReport} = FindMarket.getSaleItemReport(tenant:find, address: address, getNFTInfo:true) var marketBids : {String : FindMarket.BidItemCollectionReport} = FindMarket.getBidsReport(tenant:find, address: address, getNFTInfo:true) return FINDReport( - bids: oldLeaseBid, + bids: [], leases: leases, - leasesBids: oldLeaseBid, + leasesBids: [], itemsForSale: items, marketBids: marketBids, ) diff --git a/scripts/getFindStatus.cdc b/scripts/getFindStatus.cdc index 08ec3f1f..582dd455 100644 --- a/scripts/getFindStatus.cdc +++ b/scripts/getFindStatus.cdc @@ -8,14 +8,17 @@ import "FungibleToken" import "FindUtils" import "Clock" import "LostAndFound" +import "FindMarket" +import "FindLeaseMarket" +import "FindLeaseMarketDirectOfferSoft" -access(all) -struct FINDReport{ +access(all) struct FINDReport{ access(all) let isDapper: Bool access(all) let profile:Profile.UserReport? access(all) let privateMode: Bool access(all) let activatedAccount: Bool access(all) let hasLostAndFoundItem: Bool + access(all) let isReadyForNameOffer: Bool access(all) let accounts : [AccountInformation]? //not sure access(all) let readyForWearables : Bool? @@ -26,17 +29,18 @@ struct FINDReport{ isDapper: Bool, hasLostAndFoundItem: Bool, accounts: [AccountInformation]?, - readyForWearables: Bool? -) { - - self.hasLostAndFoundItem=hasLostAndFoundItem - self.profile=profile - self.privateMode=privateMode - self.activatedAccount=activatedAccount - self.isDapper=isDapper - self.accounts=accounts - self.readyForWearables=readyForWearables -} + readyForWearables: Bool?, + isReadyForNameOffer: Bool) { + + self.hasLostAndFoundItem=hasLostAndFoundItem + self.profile=profile + self.privateMode=privateMode + self.activatedAccount=activatedAccount + self.isDapper=isDapper + self.accounts=accounts + self.readyForWearables=readyForWearables + self.isReadyForNameOffer=isReadyForNameOffer + } } access(all) struct AccountInformation { @@ -161,6 +165,14 @@ fun main(user: String) : FINDReport? { } } + let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())! + let leaseTenant = leaseTenantCapability.borrow()! + + let leaseDOSSaleItemType= Type<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>() + let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType) + let leaseDOSSaleItemCap= account.capabilities.get<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(leaseDOSPublicPath) + let readyForLeaseOffer =leaseDOSSaleItemCap.check() + return FINDReport( profile: profileReport, privateMode: profile?.isPrivateModeEnabled() ?? false, @@ -169,6 +181,7 @@ fun main(user: String) : FINDReport? { hasLostAndFoundItem: hasLostAndFoundItem, accounts: accounts, readyForWearables: readyForWearables, + isReadyForNameOffer: readyForLeaseOffer ) } diff --git a/setup_test.go b/setup_test.go index 195c2349..c014f63f 100644 --- a/setup_test.go +++ b/setup_test.go @@ -29,7 +29,7 @@ func TestMain(m *testing.M) { var err error ot, err = SetupTest([]OverflowOption{ WithCoverageReport(), - WithFlowForNewUsers(100.0), + WithFlowForNewUsers(500.0), }, SetupFIND) if err != nil { panic(err) @@ -113,7 +113,7 @@ func SetupFIND(o *OverflowState) error { stx("register", WithSigner("find"), WithArg("name", "find"), - WithArg("amount", 100.0), + WithArg("maxAmount", 200.1), ) createUser(stx, 100.0, "find-admin") @@ -121,7 +121,7 @@ func SetupFIND(o *OverflowState) error { stx("register", WithSigner("find-admin"), WithArg("name", "find-admin"), - WithArg("amount", 5.0), + WithArg("maxAmount", 10.1), ) // setup find forge stx("setup_find_forge_1", WithSigner("find-forge")) @@ -142,14 +142,14 @@ func SetupFIND(o *OverflowState) error { stx("register", WithSigner("user1"), WithArg("name", "user1"), - WithArg("amount", 5.0), + WithArg("maxAmount", 10.0), ) stx("buyAddon", WithSigner("user1"), WithArg("name", "user1"), WithArg("addon", "forge"), - WithArg("amount", 50.0), + WithArg("maxAmount", 100.0), ) createUser(stx, 100.0, "user2") @@ -157,7 +157,7 @@ func SetupFIND(o *OverflowState) error { stx("register", WithSigner("user2"), WithArg("name", "user2"), - WithArg("amount", 5.0), + WithArg("maxAmount", 10.0), ) createUser(stx, 100.0, "user3") @@ -424,6 +424,13 @@ func SetupFIND(o *OverflowState) error { WithArg("cut", 0.0), ) + stx("tenantsetLeaseOptionMarket", + WithSigner("find"), + WithArg("nftName", "Lease"), + WithArg("nftType", findleaseQI), + WithArg("cut", 0.0), + ) + return nil } diff --git a/tasks/nfg/main.go b/tasks/nfg/main.go index 21b3bcc2..c5d2eeb4 100644 --- a/tasks/nfg/main.go +++ b/tasks/nfg/main.go @@ -5,7 +5,6 @@ import ( ) func main() { - o := Overflow(WithGlobalPrintOptions()) name := "nonfungerbils" @@ -14,7 +13,7 @@ func main() { nameArg := WithArg("name", name) saSigner := WithSignerServiceAccount() - //setup find + // setup find o.Tx("setup_fin_1_create_client", findSigner) o.Tx("setup_fin_2_register_client", saSigner, WithArg("ownerAddress", "find")) o.Tx("setup_fin_3_create_network", findSigner) @@ -23,10 +22,10 @@ func main() { o.Tx("setup_find_market_1", WithSigner("user4")) o.Tx("setup_find_lease_market_2", WithSigner("find"), WithArg("tenantAddress", "user4")) - //setnup NFG + // setnup NFG o.Tx("createProfile", nameSigner, nameArg) o.Tx("devMintFusd", WithSignerServiceAccount(), WithArg("recipient", "user1"), WithArg("amount", 1000.0)) - o.Tx("register", nameSigner, nameArg, WithArg("amount", 5.0)) + o.Tx("register", nameSigner, nameArg, WithArg("maxAmount", 10.0)) o.Tx("adminAddForge", findSigner, diff --git a/test_utils.go b/test_utils.go index 188a62e9..39e0e871 100644 --- a/test_utils.go +++ b/test_utils.go @@ -73,22 +73,22 @@ func (otu *OverflowTestUtils) registerUserTransaction(name string) OverflowResul return otu.O.Tx("register", WithSigner(name), WithArg("name", name), - WithArg("amount", 5.0), + WithArg("maxAmount", 10.0), ).AssertSuccess(otu.T). AssertEvent(otu.T, "FIND.Register", map[string]interface{}{ "validUntil": expireTime, "lockedUntil": lockedTime, "owner": nameAddress, "name": name, - }) //. TODO: This is failing, need to fix this - // AssertEvent(otu.T, "FungibleToken.Deposited", map[string]interface{}{ - // "amount": 5.0, - // "to": otu.O.Address("find-admin"), - // }). - // AssertEvent(otu.T, "FungibleToken.Withdrawn", map[string]interface{}{ - // "amount": 5.0, - // "from": nameAddress, - // }) + }). + AssertEvent(otu.T, ".FungibleToken.Deposited", map[string]interface{}{ + "amount": 10.0, + "to": otu.O.Address("find-admin"), + }). + AssertEvent(otu.T, ".FungibleToken.Withdrawn", map[string]interface{}{ + "amount": 10.0, + "from": nameAddress, + }) } func (otu *OverflowTestUtils) registerUserWithName(buyer, name string) *OverflowTestUtils { @@ -103,7 +103,7 @@ func (otu *OverflowTestUtils) registerUserWithNameTransaction(buyer, name string return otu.O.Tx("register", WithSigner(buyer), WithArg("name", name), - WithArg("amount", 5.0), + WithArg("maxAmount", 10.0), ).AssertSuccess(otu.T). AssertEvent(otu.T, "FIND.Register", map[string]interface{}{ "validUntil": expireTime, @@ -112,11 +112,11 @@ func (otu *OverflowTestUtils) registerUserWithNameTransaction(buyer, name string "name": name, }). AssertEvent(otu.T, "FungibleToken.Deposited", map[string]interface{}{ - "amount": 5.0, + "amount": 10.0, "to": otu.O.Address("find-admin"), }). AssertEvent(otu.T, "FungibleToken.Withdrawn", map[string]interface{}{ - "amount": 5.0, + "amount": 10.0, "from": nameAddress, }) } @@ -219,7 +219,7 @@ func (otu *OverflowTestUtils) buyForge(user string) *OverflowTestUtils { WithSigner(user), WithArg("name", user), WithArg("addon", "forge"), - WithArg("amount", 50.0), + WithArg("maxAmount", 100.0), ). AssertSuccess(otu.T). AssertEvent(otu.T, "FIND.AddonActivated", map[string]interface{}{ @@ -338,6 +338,29 @@ func (otu *OverflowTestUtils) listNFTForSoftAuction(name string, id uint64, pric return otu } +func (otu *OverflowTestUtils) listLeaseForSoftAuctionFlow(user string, name string, price float64) *OverflowTestUtils { + otu.O.Tx("listLeaseForAuctionSoft", + WithSigner(user), + WithArg("leaseName", name), + WithArg("ftAliasOrIdentifier", "Flow"), + WithArg("price", price), + WithArg("auctionReservePrice", price+5.0), + WithArg("auctionDuration", 300.0), + WithArg("auctionExtensionOnLateBid", 60.0), + WithArg("minimumBidIncrement", 1.0), + WithArg("auctionValidUntil", otu.currentTime()+100.0), + ). + AssertSuccess(otu.T). + AssertEvent(otu.T, "FindLeaseMarketAuctionSoft.EnglishAuction", map[string]interface{}{ + "status": "active_listed", + "amount": price, + "auctionReservePrice": price + 5.0, + "seller": otu.O.Address(user), + }) + + return otu +} + func (otu *OverflowTestUtils) listLeaseForSoftAuction(user string, name string, price float64) *OverflowTestUtils { otu.O.Tx("listLeaseForAuctionSoftDapper", WithSigner(user), @@ -496,6 +519,22 @@ func (otu *OverflowTestUtils) auctionBidMarketSoft(name string, seller string, i return otu } +func (otu *OverflowTestUtils) auctionBidLeaseMarketSoftFlow(buyer string, name string, price float64) *OverflowTestUtils { + otu.O.Tx("bidLeaseMarketAuctionSoft", + WithSigner(buyer), + WithArg("leaseName", name), + WithArg("amount", price), + ). + AssertSuccess(otu.T). + AssertEvent(otu.T, "FindLeaseMarketAuctionSoft.EnglishAuction", map[string]interface{}{ + "amount": price, + "buyer": otu.O.Address(buyer), + "status": "active_ongoing", + }) + + return otu +} + func (otu *OverflowTestUtils) auctionBidLeaseMarketSoft(buyer string, name string, price float64) *OverflowTestUtils { otu.O.Tx("bidLeaseMarketAuctionSoftDapper", WithSigner(buyer), @@ -608,6 +647,23 @@ func (otu *OverflowTestUtils) directOfferMarketSoft(name string, seller string, return otu } +func (otu *OverflowTestUtils) directOfferLeaseMarketSoftFlow(user string, name string, price float64) *OverflowTestUtils { + otu.O.Tx("bidLeaseMarketDirectOfferSoft", + WithSigner(user), + WithArg("leaseName", name), + WithArg("ftAliasOrIdentifier", "Flow"), + WithArg("amount", price), + WithArg("validUntil", otu.currentTime()+100.0), + ). + AssertSuccess(otu.T). + AssertEvent(otu.T, "FindLeaseMarketDirectOfferSoft.DirectOffer", map[string]interface{}{ + "amount": price, + "buyer": otu.O.Address(user), + }) + + return otu +} + func (otu *OverflowTestUtils) directOfferLeaseMarketSoft(user string, name string, price float64) *OverflowTestUtils { otu.O.Tx("bidLeaseMarketDirectOfferSoftDapper", WithSigner(user), @@ -659,6 +715,22 @@ func (otu *OverflowTestUtils) acceptDirectOfferMarketSoft(name string, id uint64 return otu } +func (otu *OverflowTestUtils) acceptLeaseDirectOfferMarketSoftFlow(buyer, seller string, name string, price float64) *OverflowTestUtils { + otu.O.Tx("acceptLeaseDirectOfferSoft", + WithSigner(seller), + WithArg("leaseName", name), + ). + AssertSuccess(otu.T). + AssertEvent(otu.T, "FindLeaseMarketDirectOfferSoft.DirectOffer", map[string]interface{}{ + "seller": otu.O.Address(seller), + "buyer": otu.O.Address(buyer), + "amount": price, + "status": "active_accepted", + }) + + return otu +} + func (otu *OverflowTestUtils) acceptLeaseDirectOfferMarketSoft(buyer, seller string, name string, price float64) *OverflowTestUtils { otu.O.Tx("acceptLeaseDirectOfferSoftDapper", WithSigner(seller), @@ -818,6 +890,22 @@ func (otu *OverflowTestUtils) fulfillMarketAuctionSoft(name string, id uint64, p return otu } +func (otu *OverflowTestUtils) fulfillLeaseMarketAuctionSoftFlow(user string, name string, price float64) *OverflowTestUtils { + otu.O.Tx("fulfillLeaseMarketAuctionSoft", + WithSigner(user), + WithArg("leaseName", name), + WithArg("amount", price), + ). + AssertSuccess(otu.T). + AssertEvent(otu.T, "FindLeaseMarketAuctionSoft.EnglishAuction", map[string]interface{}{ + "buyer": otu.O.Address(user), + "amount": price, + "status": "sold", + }) + + return otu +} + func (otu *OverflowTestUtils) fulfillLeaseMarketAuctionSoft(user string, name string, price float64) *OverflowTestUtils { otu.O.Tx("fulfillLeaseMarketAuctionSoftDapper", WithSigner(user), @@ -870,6 +958,22 @@ func (otu *OverflowTestUtils) fulfillLeaseMarketDirectOfferSoft(user, name strin return otu } +func (otu *OverflowTestUtils) fulfillLeaseMarketDirectOfferSoftFlow(user, name string, price float64) *OverflowTestUtils { + otu.O.Tx("fulfillLeaseMarketDirectOfferSoft", + WithSigner(user), + WithArg("leaseName", name), + WithArg("amount", price), + ). + AssertSuccess(otu.T). + AssertEvent(otu.T, "FindLeaseMarketDirectOfferSoft.DirectOffer", map[string]interface{}{ + "buyer": otu.O.Address(user), + "amount": price, + "status": "sold", + }) + + return otu +} + type Cap struct { Address string Id uint64 @@ -1122,6 +1226,23 @@ func (otu *OverflowTestUtils) listNFTForSaleDUC(name string, id uint64, price fl return res } +func (otu *OverflowTestUtils) listLeaseForSale(user string, name string, price float64) *OverflowTestUtils { + ftIden, err := otu.O.QualifiedIdentifier("FlowToken", "Vault") + assert.NoError(otu.T, err) + + res := otu.O.Tx("listLeaseForSale", + WithSigner(user), + WithArg("leaseName", name), + WithArg("ftAliasOrIdentifier", ftIden), + WithArg("directSellPrice", price), + WithArg("validUntil", otu.currentTime()+100.0), + ) + + res.AssertSuccess(otu.T) + + return otu +} + func (otu *OverflowTestUtils) listLeaseForSaleDUC(user string, name string, price float64) *OverflowTestUtils { ftIden, err := otu.O.QualifiedIdentifier("DapperUtilityCoin", "Vault") assert.NoError(otu.T, err) @@ -1178,6 +1299,42 @@ func (otu *OverflowTestUtils) buyLeaseForMarketSaleDUC(buyer, seller, name strin return otu } +func (otu *OverflowTestUtils) buyLeaseForMarketSale(buyer, seller, name string, price float64) *OverflowTestUtils { + amount := price * 0.025 + + eventIden, err := otu.O.QualifiedIdentifier("FindLeaseMarketSale", "Sale") + assert.NoError(otu.T, err) + + otu.O.Tx("buyLeaseForSale", + WithSigner(buyer), + WithArg("leaseName", name), + WithArg("amount", price), + ). + AssertSuccess(otu.T). + AssertEvent(otu.T, eventIden, map[string]interface{}{ + "amount": price, + "seller": otu.O.Address(seller), + "buyer": otu.O.Address(buyer), + "status": "sold", + }). + AssertEvent(otu.T, "RoyaltyPaid", map[string]interface{}{ + "amount": amount, + "address": otu.O.Address("find"), + "royaltyName": "find", + "tenant": "find", + }) + /*. + AssertEvent(otu.T, "RoyaltyPaid", map[string]interface{}{ + "amount": dapperAmount, + "address": otu.O.Address("dapper"), + "royaltyName": "dapper", + "tenant": "find", + }) + */ + + return otu +} + func (otu *OverflowTestUtils) listNFTForSoftAuctionDUC(name string, id uint64, price float64) []uint64 { ftIden, err := otu.O.QualifiedIdentifier("DapperUtilityCoin", "Vault") assert.NoError(otu.T, err) diff --git a/testdata/TestNFTDetailScript/Should_be_able_to_get_nft_details_of_item_with_views.golden b/testdata/TestNFTDetailScript/Should_be_able_to_get_nft_details_of_item_with_views.golden index 4ab5fdd0..9764cd7a 100644 --- a/testdata/TestNFTDetailScript/Should_be_able_to_get_nft_details_of_item_with_views.golden +++ b/testdata/TestNFTDetailScript/Should_be_able_to_get_nft_details_of_item_with_views.golden @@ -136,7 +136,7 @@ test_main.NFTDetailsReturnData{ "receiver": map[string]interface{}{ "address": "0x192440c99cb17282", "borrowType": "&{A.ee82856bf20e2aa6.FungibleToken.Receiver}", - "id": 10, + "id": 9, }, }, map[string]interface{}{ @@ -145,7 +145,7 @@ test_main.NFTDetailsReturnData{ "receiver": map[string]interface{}{ "address": "0xf3fcd2c1a78f5eee", "borrowType": "&{A.ee82856bf20e2aa6.FungibleToken.Receiver}", - "id": 33, + "id": 32, }, }, }}, diff --git a/transactions/acceptLeaseDirectOfferSoft.cdc b/transactions/acceptLeaseDirectOfferSoft.cdc index 083abb8d..cfbab5c2 100644 --- a/transactions/acceptLeaseDirectOfferSoft.cdc +++ b/transactions/acceptLeaseDirectOfferSoft.cdc @@ -8,22 +8,33 @@ import "FIND" transaction(leaseName: String) { - let market : &FindLeaseMarketDirectOfferSoft.SaleItemCollection - let pointer : FindLeaseMarket.AuthLeasePointer - - prepare(account: auth(BorrowValue) &Account) { - let marketplace = FindMarket.getFindTenantAddress() - let tenant=FindMarket.getTenant(marketplace) - let storagePath=tenant.getStoragePath(Type<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>()) - self.market = account.storage.borrow<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(from: storagePath)! - let marketOption = FindMarket.getMarketOptionFromType(Type<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>()) - let item = FindLeaseMarket.assertOperationValid(tenant: marketplace, name: leaseName, marketOption: marketOption) - let ref = account.capabilities.storage.get(from: FIND.LeaseStoragePath) ?? panic("Cannot borrow reference to find lease collection. Account : ".concat(account.address.toString())) - self.pointer= FindLeaseMarket.AuthLeasePointer(ref: ref, name: leaseName) - } - - execute { - self.market.acceptOffer(self.pointer) - } + let market : auth(FindLeaseMarketDirectOfferSoft.Seller) &FindLeaseMarketDirectOfferSoft.SaleItemCollection + let pointer : FindLeaseMarket.AuthLeasePointer + + prepare(account: auth(Storage, IssueStorageCapabilityController) &Account) { + let marketplace = FindMarket.getFindTenantAddress() + let tenant=FindMarket.getTenant(marketplace) + let storagePath=tenant.getStoragePath(Type<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>()) + self.market = account.storage.borrow(from: storagePath)! + + + let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:"/")[1] + let providerIdentifier = storagePathIdentifer.concat("ProviderFlow") + let providerStoragePath = StoragePath(identifier: providerIdentifier)! + + var existingProvider= account.storage.copy>(from: providerStoragePath) + if existingProvider==nil { + existingProvider=account.capabilities.storage.issue(FIND.LeaseStoragePath) + account.storage.save(existingProvider!, to: providerStoragePath) + } + var cap = existingProvider! + self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName) + + + } + + execute { + self.market.acceptOffer(self.pointer) + } } diff --git a/transactions/acceptLeaseDirectOfferSoftDapper.cdc b/transactions/acceptLeaseDirectOfferSoftDapper.cdc index 824fda30..bb2818d7 100644 --- a/transactions/acceptLeaseDirectOfferSoftDapper.cdc +++ b/transactions/acceptLeaseDirectOfferSoftDapper.cdc @@ -4,7 +4,6 @@ import "MetadataViews" import "FindViews" import "FindMarket" import "FindLeaseMarket" -import "FungibleToken" import "FIND" transaction(leaseName: String) { diff --git a/transactions/bidLeaseMarketDirectOfferSoft.cdc b/transactions/bidLeaseMarketDirectOfferSoft.cdc index 88105215..5f7150af 100644 --- a/transactions/bidLeaseMarketDirectOfferSoft.cdc +++ b/transactions/bidLeaseMarketDirectOfferSoft.cdc @@ -8,7 +8,7 @@ import "FindLeaseMarketDirectOfferSoft" transaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, validUntil: UFix64?) { - let bidsReference: &FindLeaseMarketDirectOfferSoft.MarketBidCollection? + let bidsReference: auth(FindLeaseMarketDirectOfferSoft.Buyer) &FindLeaseMarketDirectOfferSoft.MarketBidCollection? let ftVaultType: Type prepare(account: auth(StorageCapabilities, SaveValue,PublishCapability, BorrowValue) &Account) { @@ -29,17 +29,20 @@ transaction(leaseName: String, ftAliasOrIdentifier:String, amount: UFix64, valid let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)! let leaseTenant = leaseTenantCapability.borrow()! - let receiverCap=account.capabilities.get<&{FungibleToken.Receiver}>(Profile.publicReceiverPath)! + + + let receiverCap=account.capabilities.get<&{FungibleToken.Receiver}>(Profile.publicReceiverPath) let leaseDOSBidType= Type<@FindLeaseMarketDirectOfferSoft.MarketBidCollection>() let leaseDOSBidPublicPath=leaseTenant.getPublicPath(leaseDOSBidType) let leaseDOSBidStoragePath= leaseTenant.getStoragePath(leaseDOSBidType) - let leaseDOSBidCap= account.getCapability<&FindLeaseMarketDirectOfferSoft.MarketBidCollection>(leaseDOSBidPublicPath) + let leaseDOSBidCap= account.capabilities.get<&FindLeaseMarketDirectOfferSoft.MarketBidCollection>(leaseDOSBidPublicPath) if !leaseDOSBidCap.check() { account.storage.save<@FindLeaseMarketDirectOfferSoft.MarketBidCollection>(<- FindLeaseMarketDirectOfferSoft.createEmptyMarketBidCollection(receiver:receiverCap, tenantCapability:leaseTenantCapability), to: leaseDOSBidStoragePath) - account.link<&FindLeaseMarketDirectOfferSoft.MarketBidCollection>(leaseDOSBidPublicPath, target: leaseDOSBidStoragePath) + let cap = account.capabilities.storage.issue<&FindLeaseMarketDirectOfferSoft.MarketBidCollection>(leaseDOSBidStoragePath) + account.capabilities.publish(cap, at: leaseDOSBidPublicPath) } - self.bidsReference= account.storage.borrow<&FindLeaseMarketDirectOfferSoft.MarketBidCollection>(from: leaseDOSBidStoragePath) + self.bidsReference= account.storage.borrow(from: leaseDOSBidStoragePath) } diff --git a/transactions/buyAddon.cdc b/transactions/buyAddon.cdc index 5e06fb91..151ab347 100644 --- a/transactions/buyAddon.cdc +++ b/transactions/buyAddon.cdc @@ -1,27 +1,30 @@ -import "FUSD" import "FIND" +import "FlowToken" import "FungibleToken" -transaction(name: String, addon:String, amount:UFix64) { +transaction(name: String, addon:String, maxAmount:UFix64) { let leases : &FIND.LeaseCollection? - let vaultRef : auth (FungibleToken.Withdraw) &FUSD.Vault? + let vaultRef : auth (FungibleToken.Withdraw) &FlowToken.Vault? + let cost: UFix64 prepare(account: auth (BorrowValue, FungibleToken.Withdraw) &Account) { self.leases= account.storage.borrow<&FIND.LeaseCollection>(from:FIND.LeaseStoragePath) - self.vaultRef = account.storage.borrow(from: /storage/fusdVault) - + self.vaultRef = account.storage.borrow(from: /storage/flowTokenVault) + self.cost=FIND.calculateAddonCostInFlow(addon) } pre{ self.leases != nil : "Could not borrow reference to the leases collection" - self.vaultRef != nil : "Could not borrow reference to the fusdVault!" + self.vaultRef != nil : "Could not borrow reference to the flow token vault!" + self.cost <= maxAmount : "You have not sent in enough max flow, the cost is ".concat(self.cost.toString()) + self.vaultRef!.balance > self.cost : "Balance of vault is not high enough ".concat(self.vaultRef!.balance.toString().concat(" total balance is ").concat(self.vaultRef!.balance.toString())) } execute { - let vault <- self.vaultRef!.withdraw(amount: amount) as! @FUSD.Vault + let vault <- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault self.leases!.buyAddon(name: name, addon: addon, vault: <- vault) } } diff --git a/transactions/buyLeaseForSale.cdc b/transactions/buyLeaseForSale.cdc new file mode 100644 index 00000000..a8015bf6 --- /dev/null +++ b/transactions/buyLeaseForSale.cdc @@ -0,0 +1,60 @@ +import "FindMarket" +import "FTRegistry" +import "FungibleToken" +import "FIND" +import "Profile" +import "FindLeaseMarketSale" +import "FindLeaseMarket" + +transaction(leaseName: String, amount: UFix64) { + + let buyer : Address + let walletReference : auth(FungibleToken.Withdraw) &{FungibleToken.Vault} + + let saleItemCollection: &{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic} + + prepare(account: auth(BorrowValue, SaveValue, IssueStorageCapabilityController) &Account) { + + let profile=account.storage.borrow<&Profile.User>(from: Profile.storagePath) ?? panic("You do not have a profile set up, initialize the user first") + + let address = FIND.resolve(leaseName) ?? panic("The address input is not a valid name nor address. Input : ".concat(leaseName)) + + if address == nil { + panic("The address input is not a valid name nor address. Input : ".concat(leaseName)) + } + + let leaseMarketplace = FindMarket.getTenantAddress("find") ?? panic("Cannot find find tenant") + let saleItemsCap= FindLeaseMarketSale.getSaleItemCapability(marketplace: leaseMarketplace, user:address) ?? panic("cannot find sale item cap for find") + + let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)! + let leaseTenant = leaseTenantCapability.borrow()! + + let leaseSaleItemType= Type<@FindLeaseMarketSale.SaleItemCollection>() + let leasePublicPath=FindMarket.getPublicPath(leaseSaleItemType, name: "find") + let leaseStoragePath= FindMarket.getStoragePath(leaseSaleItemType, name:"find") + var leaseSaleItemCap= account.capabilities.get<&{FindLeaseMarketSale.SaleItemCollectionPublic, FindLeaseMarket.SaleItemCollectionPublic}>(leasePublicPath) + if !leaseSaleItemCap.check(){ + //The link here has to be a capability not a tenant, because it can change. + account.storage.save<@FindLeaseMarketSale.SaleItemCollection>(<- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) + leaseSaleItemCap= account.capabilities.storage.issue<&{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}>(leaseStoragePath) + } + + self.saleItemCollection = saleItemsCap.borrow()! + let item = self.saleItemCollection.borrowSaleItem(leaseName) + + let ft = FTRegistry.getFTInfoByTypeIdentifier(item.getFtType().identifier) ?? panic("This FT is not supported by the Find Market yet. Type : ".concat(item.getFtType().identifier)) + + + self.walletReference = account.storage.borrow(from: ft.vaultPath) ?? panic("No suitable wallet linked for this account") + self.buyer = account.address + } + + pre { + self.walletReference.balance > amount : "Your wallet does not have enough funds to pay for this item" + } + + execute { + let vault <- self.walletReference.withdraw(amount: amount) + self.saleItemCollection.buy(name:leaseName, vault: <- vault, to: self.buyer) + } +} diff --git a/transactions/createProfile.cdc b/transactions/createProfile.cdc index 6b4ac00f..a71e66e0 100644 --- a/transactions/createProfile.cdc +++ b/transactions/createProfile.cdc @@ -9,8 +9,9 @@ import "FindPack" import "Profile" import "FindMarket" import "FindMarketDirectOfferEscrow" +import "FindLeaseMarketDirectOfferSoft" +import "FindLeaseMarket" import "Dandy" -//import "FindThoughts" transaction(name: String) { prepare(account: auth (Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) &Account) { @@ -49,15 +50,6 @@ transaction(name: String) { account.capabilities.publish(cap, at: FIND.LeasePublicPath) } - let bidCollection = account.capabilities.get<&FIND.BidCollection>(FIND.BidPublicPath) - if !bidCollection.check(){ - let fr = account.capabilities.get<&{FungibleToken.Receiver}>(/public/fusdReceiver) - let lc = account.capabilities.get<&FIND.LeaseCollection>(FIND.LeasePublicPath) - account.storage.save(<- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath) - let cap = account.capabilities.storage.issue<&FIND.BidCollection>(FIND.BidStoragePath) - account.capabilities.publish(cap, at: FIND.BidPublicPath) - } - let dandyCap= account.capabilities.get<&{NonFungibleToken.Collection}>(Dandy.CollectionPublicPath) if !dandyCap.check() { account.storage.save(<- Dandy.createEmptyCollection(nftType:Type<@Dandy.NFT>()), to: Dandy.CollectionStoragePath) @@ -141,5 +133,20 @@ transaction(name: String) { let cap = account.capabilities.storage.issue<&{FindMarketDirectOfferEscrow.SaleItemCollectionPublic, FindMarket.SaleItemCollectionPublic}>(doeSaleStoragePath) account.capabilities.publish(cap, at: doeSalePublicPath) } + + let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())! + let leaseTenant = leaseTenantCapability.borrow()! + + let leaseDOSSaleItemType= Type<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>() + let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType) + let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType) + let leaseDOSSaleItemCap= account.capabilities.get<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(leaseDOSPublicPath) + if !leaseDOSSaleItemCap.check() { + //The link here has to be a capability not a tenant, because it can change. + account.storage.save<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>(<- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath) + let leaseDOSSaleItemCap = account.capabilities.storage.issue<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(leaseDOSStoragePath) + account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath) + } + } } diff --git a/transactions/createProfileDapper.cdc b/transactions/createProfileDapper.cdc index 65393917..d57814ea 100644 --- a/transactions/createProfileDapper.cdc +++ b/transactions/createProfileDapper.cdc @@ -15,6 +15,7 @@ import "FindViews" transaction(name: String) { prepare(account: auth(Profile.Admin, StorageCapabilities, SaveValue,PublishCapability, BorrowValue) &Account) { + let leaseCollection = account.capabilities.get<&FIND.LeaseCollection>(FIND.LeasePublicPath) if !leaseCollection.check() { account.storage.save(<- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath) diff --git a/transactions/editProfile.cdc b/transactions/editProfile.cdc index b8e9dcbf..ec70dcaf 100644 --- a/transactions/editProfile.cdc +++ b/transactions/editProfile.cdc @@ -3,6 +3,8 @@ import "FUSD" import "FlowToken" import "FIND" import "Profile" +import "FindMarket" +import "FindLeaseMarketDirectOfferSoft" transaction(name:String, description: String, avatar: String, tags:[String], allowStoringFollowers: Bool, linkTitles : {String: String}, linkTypes: {String:String}, linkUrls : {String:String}, removeLinks : [String]) { @@ -64,14 +66,18 @@ transaction(name:String, description: String, avatar: String, tags:[String], all account.capabilities.publish(cap, at: FIND.LeasePublicPath) } - - let bidCollection = account.capabilities.get<&FIND.BidCollection>(FIND.BidPublicPath) - if !bidCollection.check() { - let fr = account.capabilities.get<&{FungibleToken.Receiver}>(/public/fusdReceiver) - let lc = account.capabilities.get<&FIND.LeaseCollection>(FIND.LeasePublicPath) - account.storage.save(<- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath) - let cap = account.capabilities.storage.issue<&FIND.BidCollection>(FIND.BidStoragePath) - account.capabilities.publish(cap, at: FIND.BidPublicPath) + let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())! + let leaseTenant = leaseTenantCapability.borrow()! + + let leaseDOSSaleItemType= Type<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>() + let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType) + let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType) + let leaseDOSSaleItemCap= account.capabilities.get<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(leaseDOSPublicPath) + if !leaseDOSSaleItemCap.check() { + //The link here has to be a capability not a tenant, because it can change. + account.storage.save<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>(<- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath) + let leaseDOSSaleItemCap = account.capabilities.storage.issue<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(leaseDOSStoragePath) + account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath) } } diff --git a/transactions/follow.cdc b/transactions/follow.cdc index 703ac635..42c22a7e 100644 --- a/transactions/follow.cdc +++ b/transactions/follow.cdc @@ -66,15 +66,6 @@ transaction(follows:{String : [String]}) { account.capabilities.publish(cap, at: FIND.LeasePublicPath) } - let bidCollection = account.capabilities.get<&FIND.BidCollection>(FIND.BidPublicPath) - if !bidCollection.check(){ - let fr = account.capabilities.get<&{FungibleToken.Receiver}>(/public/fusdReceiver) - let lc = account.capabilities.get<&FIND.LeaseCollection>(FIND.LeasePublicPath) - account.storage.save(<- FIND.createEmptyBidCollection(receiver: fr, leases: lc), to: FIND.BidStoragePath) - let cap = account.capabilities.storage.issue<&FIND.BidCollection>(FIND.BidStoragePath) - account.capabilities.publish(cap, at: FIND.BidPublicPath) - } - } execute{ diff --git a/transactions/linkForLeaseMarket.cdc b/transactions/linkForLeaseMarket.cdc new file mode 100644 index 00000000..a64c5256 --- /dev/null +++ b/transactions/linkForLeaseMarket.cdc @@ -0,0 +1,20 @@ +import "FindLeaseMarketDirectOfferSoft" +import "FindMarket" + +transaction() { + prepare(account: auth (StorageCapabilities, SaveValue,PublishCapability, BorrowValue) &Account) { + let leaseTenantCapability= FindMarket.getTenantCapability(FindMarket.getFindTenantAddress())! + let leaseTenant = leaseTenantCapability.borrow()! + + let leaseDOSSaleItemType= Type<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>() + let leaseDOSPublicPath=leaseTenant.getPublicPath(leaseDOSSaleItemType) + let leaseDOSStoragePath= leaseTenant.getStoragePath(leaseDOSSaleItemType) + let leaseDOSSaleItemCap= account.capabilities.get<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(leaseDOSPublicPath) + if !leaseDOSSaleItemCap.check() { + //The link here has to be a capability not a tenant, because it can change. + account.storage.save<@FindLeaseMarketDirectOfferSoft.SaleItemCollection>(<- FindLeaseMarketDirectOfferSoft.createEmptySaleItemCollection(leaseTenantCapability), to: leaseDOSStoragePath) + let leaseDOSSaleItemCap = account.capabilities.storage.issue<&FindLeaseMarketDirectOfferSoft.SaleItemCollection>(leaseDOSStoragePath) + account.capabilities.publish(leaseDOSSaleItemCap, at: leaseDOSPublicPath) + } + } +} diff --git a/transactions/listLeaseForAuctionSoft.cdc b/transactions/listLeaseForAuctionSoft.cdc index 090b4890..b545df09 100644 --- a/transactions/listLeaseForAuctionSoft.cdc +++ b/transactions/listLeaseForAuctionSoft.cdc @@ -34,7 +34,7 @@ transaction(leaseName: String, ftAliasOrIdentifier:String, price:UFix64, auction let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:"/")[1] - let providerIdentifier = storagePathIdentifer.concat("Provider") + let providerIdentifier = storagePathIdentifer.concat("ProviderFlow") let providerStoragePath = StoragePath(identifier: providerIdentifier)! var existingProvider= account.storage.copy>(from: providerStoragePath) diff --git a/transactions/listLeaseForSale.cdc b/transactions/listLeaseForSale.cdc new file mode 100644 index 00000000..ee993c11 --- /dev/null +++ b/transactions/listLeaseForSale.cdc @@ -0,0 +1,61 @@ +import "FindMarket" +import "FIND" +import "FTRegistry" +import "FindLeaseMarketSale" +import "FindLeaseMarket" +import "FindMarketSale" + +transaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix64, validUntil: UFix64?) { + + let saleItems : auth(FindLeaseMarketSale.Seller) &FindLeaseMarketSale.SaleItemCollection + let pointer : FindLeaseMarket.AuthLeasePointer + let vaultType : Type + + prepare(account: auth(Storage, IssueStorageCapabilityController, PublishCapability, IssueStorageCapabilityController) &Account) { + + // Get the salesItemRef from tenant + let leaseMarketplace = FindMarket.getFindTenantAddress() + let leaseTenantCapability= FindMarket.getTenantCapability(leaseMarketplace)! + let leaseTenant = leaseTenantCapability.borrow()! + + let leaseSaleItemType= Type<@FindLeaseMarketSale.SaleItemCollection>() + let leasePublicPath=leaseTenant.getPublicPath(leaseSaleItemType) + let leaseStoragePath= leaseTenant.getStoragePath(leaseSaleItemType) + let leaseSaleItemCap= account.capabilities.get<&{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}>(leasePublicPath) + if !leaseSaleItemCap.check() { + //The link here has to be a capability not a tenant, because it can change. + account.storage.save<@FindLeaseMarketSale.SaleItemCollection>(<- FindLeaseMarketSale.createEmptySaleItemCollection(leaseTenantCapability), to: leaseStoragePath) + let leaseSaleItemCap= account.capabilities.storage.issue<&{FindLeaseMarket.SaleItemCollectionPublic, FindLeaseMarketSale.SaleItemCollectionPublic}>(leaseStoragePath) + account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath) + } + + + self.saleItems= account.storage.borrow(from: leaseStoragePath)! + + // Get supported NFT and FT Information from Registries from input alias + let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic("This FT is not supported by the Find Market yet. Type : ".concat(ftAliasOrIdentifier)) + self.vaultType= ft.type + + let storagePathIdentifer = FIND.LeaseStoragePath.toString().split(separator:"/")[1] + let providerIdentifier = storagePathIdentifer.concat("ProviderFlow") + let providerStoragePath = StoragePath(identifier: providerIdentifier)! + + var existingProvider= account.storage.copy>(from: providerStoragePath) + if existingProvider==nil { + existingProvider=account.capabilities.storage.issue(FIND.LeaseStoragePath) + account.storage.save(existingProvider!, to: providerStoragePath) + } + var cap = existingProvider! + self.pointer= FindLeaseMarket.AuthLeasePointer(cap: cap, name: leaseName) + } + + pre{ + self.saleItems != nil : "Cannot borrow reference to saleItem" + } + + execute{ + self.saleItems.listForSale(pointer: self.pointer, vaultType: self.vaultType, directSellPrice: directSellPrice, validUntil: validUntil, extraField: {}) + } + +} + diff --git a/transactions/listLeaseForSaleDapper.cdc b/transactions/listLeaseForSaleDapper.cdc index 3c767e91..a63fd4b5 100644 --- a/transactions/listLeaseForSaleDapper.cdc +++ b/transactions/listLeaseForSaleDapper.cdc @@ -29,10 +29,7 @@ transaction(leaseName: String, ftAliasOrIdentifier: String, directSellPrice:UFix account.capabilities.publish(leaseSaleItemCap, at: leasePublicPath) } - self.saleItems= account.storage.borrow(from: leaseStoragePath)! - - // Get supported NFT and FT Information from Registries from input alias let ft = FTRegistry.getFTInfo(ftAliasOrIdentifier) ?? panic("This FT is not supported by the Find Market yet. Type : ".concat(ftAliasOrIdentifier)) self.vaultType= ft.type diff --git a/transactions/register.cdc b/transactions/register.cdc index 88c46c75..283e17f3 100644 --- a/transactions/register.cdc +++ b/transactions/register.cdc @@ -1,31 +1,32 @@ -import "FUSD" +import "FlowToken" import "FIND" import "FungibleToken" -transaction(name: String, amount: UFix64) { +transaction(name: String, maxAmount: UFix64) { - let vaultRef : auth(FungibleToken.Withdraw) &FUSD.Vault? + let vaultRef : auth(FungibleToken.Withdraw) &FlowToken.Vault? let leases : auth(FIND.LeaseOwner) &FIND.LeaseCollection? - let price : UFix64 + let cost : UFix64 prepare(account: auth(BorrowValue) &Account) { - self.price=FIND.calculateCost(name) - log("The cost for registering this name is ".concat(self.price.toString())) - self.vaultRef = account.storage.borrow(from: /storage/fusdVault) + self.vaultRef = account.storage.borrow(from: /storage/flowTokenVault) self.leases=account.storage.borrow(from: FIND.LeaseStoragePath) + + self.cost = FIND.calculateCostInFlow(name) + } + pre{ + self.cost <= maxAmount : "You have not sent in enough max flow, the cost is ".concat(self.cost.toString()) self.vaultRef != nil : "Could not borrow reference to the fusdVault!" self.leases != nil : "Could not borrow reference to find lease collection" - self.price == amount : "Calculated cost : ".concat(self.price.toString()).concat(" does not match expected cost : ").concat(amount.toString()) + self.vaultRef!.balance > self.cost : "Balance of vault is not high enough ".concat(self.cost.toString()).concat(" total balance is ").concat(self.vaultRef!.balance.toString()) } execute{ - let payVault <- self.vaultRef!.withdraw(amount: self.price) as! @FUSD.Vault - - //TODO: entitlements + let payVault <- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault self.leases!.register(name: name, vault: <- payVault) } } diff --git a/transactions/renewName.cdc b/transactions/renewName.cdc index d9540d22..e3c0dba0 100644 --- a/transactions/renewName.cdc +++ b/transactions/renewName.cdc @@ -1,27 +1,29 @@ -import "FUSD" +import "FlowToken" import "FungibleToken" import "FIND" -transaction(name: String, amount: UFix64) { +transaction(name: String, maxAmount: UFix64) { - let price : UFix64 - let vaultRef : auth (FungibleToken.Withdraw) &FUSD.Vault? + let cost : UFix64 + let vaultRef : auth (FungibleToken.Withdraw) &FlowToken.Vault? let finLeases : auth(FIND.LeaseOwner) &FIND.LeaseCollection? prepare(acct: auth(BorrowValue) &Account) { - self.price=FIND.calculateCost(name) - self.vaultRef = acct.storage.borrow(from: /storage/fusdVault) + self.cost=FIND.calculateCostInFlow(name) + self.vaultRef = acct.storage.borrow(from: /storage/flowTokenVault) self.finLeases= acct.storage.borrow(from:FIND.LeaseStoragePath) } + pre{ - self.price == amount : "expected renew cost : ".concat(self.price.toString()).concat(" is not the same as calculated renew cost : ").concat(amount.toString()) self.vaultRef != nil : "Could not borrow reference to the fusdVault!" self.finLeases != nil : "Could not borrow reference to find lease collection" + self.cost <= maxAmount : "You have not sent in enough max flow, the cost is ".concat(self.cost.toString()) + self.vaultRef!.balance > self.cost : "Balance of vault is not high enough ".concat(self.vaultRef!.balance.toString().concat(" total balance is ").concat(self.vaultRef!.balance.toString())) } execute{ - let payVault <- self.vaultRef!.withdraw(amount: self.price) + let payVault <- self.vaultRef!.withdraw(amount: self.cost) as! @FlowToken.Vault let finToken= self.finLeases!.borrow(name) finToken.extendLease(<- payVault) } diff --git a/transactions/sendFTWithTag.cdc b/transactions/sendFTWithTag.cdc index ba06fe7d..6a460479 100644 --- a/transactions/sendFTWithTag.cdc +++ b/transactions/sendFTWithTag.cdc @@ -11,84 +11,78 @@ import "CharityNFT" transaction(name: String, amount: UFix64, type: String, tag:String) { - prepare(account: auth(BorrowValue) &Account) { - - let stdCap= account.getCapability<&{NonFungibleToken.Collection}>(CharityNFT.CollectionPublicPath) - if !stdCap.check() { - account.storage.save<@NonFungibleToken.Collection>(<- CharityNFT.createEmptyCollection(), to: CharityNFT.CollectionStoragePath) - account.link<&{NonFungibleToken.Collection, ViewResolver.ResolverCollection}>(CharityNFT.CollectionPublicPath, target: CharityNFT.CollectionStoragePath) - } - - let charityCap = account.getCapability<&{CharityNFT.CollectionPublic}>(/public/findCharityNFTCollection) - if !charityCap.check() { - account.link<&{CharityNFT.CollectionPublic, ViewResolver.ResolverCollection}>(/public/findCharityNFTCollection, target: CharityNFT.CollectionStoragePath) - } - - let fusdReceiver = account.getCapability<&{FungibleToken.Receiver}>(/public/fusdReceiver) - if !fusdReceiver.check() { - let fusd <- FUSD.createEmptyVault(vaultType: Type<@FUSD.Vault>()) - account.storage.save(<- fusd, to: /storage/fusdVault) - account.link<&FUSD.Vault{FungibleToken.Receiver}>( /public/fusdReceiver, target: /storage/fusdVault) - account.link<&FUSD.Vault{FungibleToken.Balance}>( /public/fusdBalance, target: /storage/fusdVault) - } - - let leaseCollection = account.getCapability<&FIND.LeaseCollection{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) - if !leaseCollection!.check() { - account.storage.save(<- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath) - account.link<&FIND.LeaseCollection{FIND.LeaseCollectionPublic}>( FIND.LeasePublicPath, target: FIND.LeaseStoragePath) - } - - let bidCollection = account.getCapability<&FIND.BidCollection{FIND.BidCollectionPublic}>(FIND.BidPublicPath) - if !bidCollection.check() { - account.storage.save(<- FIND.createEmptyBidCollection(receiver: fusdReceiver, leases: leaseCollection), to: FIND.BidStoragePath) - account.link<&FIND.BidCollection{FIND.BidCollectionPublic}>( FIND.BidPublicPath, target: FIND.BidStoragePath) - } - - let profileCap = account.getCapability<&{Profile.Public}>(Profile.publicPath) - if !profileCap.check() { - let profileName = account.address.toString() - - let profile <-Profile.createUser(name:profileName, createdAt: "find") - - let fusdWallet=Profile.Wallet( name:"FUSD", receiver:fusdReceiver, balance:account.getCapability<&{FungibleToken.Balance}>(/public/fusdBalance), accept: Type<@FUSD.Vault>(), names: ["fusd", "stablecoin"]) - - profile.addWallet(fusdWallet) - - let flowWallet=Profile.Wallet( - name:"Flow", - receiver:account.getCapability<&{FungibleToken.Receiver}>(/public/flowTokenReceiver), - balance:account.getCapability<&{FungibleToken.Balance}>(/public/flowTokenBalance), - accept: Type<@FlowToken.Vault>(), - names: ["flow"] - ) - - profile.addWallet(flowWallet) - profile.addCollection(Profile.ResourceCollection("FINDLeases",leaseCollection, Type<&FIND.LeaseCollection{FIND.LeaseCollectionPublic}>(), ["find", "leases"])) - profile.addCollection(Profile.ResourceCollection("FINDBids", bidCollection, Type<&FIND.BidCollection{FIND.BidCollectionPublic}>(), ["find", "bids"])) - - account.storage.save(<-profile, to: Profile.storagePath) - account.link<&Profile.User{Profile.Public}>(Profile.publicPath, target: Profile.storagePath) - account.link<&{FungibleToken.Receiver}>(Profile.publicReceiverPath, target: Profile.storagePath) - } - - if account.storage.borrow<&Sender.Token>(from: Sender.storagePath) == nil { - account.storage.save(<- Sender.create(), to: Sender.storagePath) - } - - let token =account.storage.borrow<&Sender.Token>(from: Sender.storagePath)! - - - if type == "fusd" { - let vaultRef = account.storage.borrow<&FUSD.Vault>(from: /storage/fusdVault) ?? panic("Could not borrow reference to the fusdVault!") - let vault <- vaultRef.withdraw(amount: amount) - FIND.depositWithTagAndMessage(to: name, message: "", tag: tag, vault: <- vault, from: token) - return - } - - let vaultRef = account.storage.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) ?? panic("Could not borrow reference to the fusdVault!") - let vault <- vaultRef.withdraw(amount: amount) - FIND.depositWithTagAndMessage(to: name, message: "", tag: tag, vault: <- vault, from: token) - } + prepare(account: auth(BorrowValue) &Account) { + + let stdCap= account.getCapability<&{NonFungibleToken.Collection}>(CharityNFT.CollectionPublicPath) + if !stdCap.check() { + account.storage.save<@NonFungibleToken.Collection>(<- CharityNFT.createEmptyCollection(), to: CharityNFT.CollectionStoragePath) + account.link<&{NonFungibleToken.Collection, ViewResolver.ResolverCollection}>(CharityNFT.CollectionPublicPath, target: CharityNFT.CollectionStoragePath) + } + + let charityCap = account.getCapability<&{CharityNFT.CollectionPublic}>(/public/findCharityNFTCollection) + if !charityCap.check() { + account.link<&{CharityNFT.CollectionPublic, ViewResolver.ResolverCollection}>(/public/findCharityNFTCollection, target: CharityNFT.CollectionStoragePath) + } + + let fusdReceiver = account.getCapability<&{FungibleToken.Receiver}>(/public/fusdReceiver) + if !fusdReceiver.check() { + let fusd <- FUSD.createEmptyVault(vaultType: Type<@FUSD.Vault>()) + account.storage.save(<- fusd, to: /storage/fusdVault) + account.link<&FUSD.Vault{FungibleToken.Receiver}>( /public/fusdReceiver, target: /storage/fusdVault) + account.link<&FUSD.Vault{FungibleToken.Balance}>( /public/fusdBalance, target: /storage/fusdVault) + } + + let leaseCollection = account.getCapability<&FIND.LeaseCollection{FIND.LeaseCollectionPublic}>(FIND.LeasePublicPath) + if !leaseCollection!.check() { + account.storage.save(<- FIND.createEmptyLeaseCollection(), to: FIND.LeaseStoragePath) + account.link<&FIND.LeaseCollection{FIND.LeaseCollectionPublic}>( FIND.LeasePublicPath, target: FIND.LeaseStoragePath) + } + + let profileCap = account.getCapability<&{Profile.Public}>(Profile.publicPath) + if !profileCap.check() { + let profileName = account.address.toString() + + let profile <-Profile.createUser(name:profileName, createdAt: "find") + + let fusdWallet=Profile.Wallet( name:"FUSD", receiver:fusdReceiver, balance:account.getCapability<&{FungibleToken.Balance}>(/public/fusdBalance), accept: Type<@FUSD.Vault>(), names: ["fusd", "stablecoin"]) + + profile.addWallet(fusdWallet) + + let flowWallet=Profile.Wallet( + name:"Flow", + receiver:account.getCapability<&{FungibleToken.Receiver}>(/public/flowTokenReceiver), + balance:account.getCapability<&{FungibleToken.Balance}>(/public/flowTokenBalance), + accept: Type<@FlowToken.Vault>(), + names: ["flow"] + ) + + profile.addWallet(flowWallet) + profile.addCollection(Profile.ResourceCollection("FINDLeases",leaseCollection, Type<&FIND.LeaseCollection{FIND.LeaseCollectionPublic}>(), ["find", "leases"])) + profile.addCollection(Profile.ResourceCollection("FINDBids", bidCollection, Type<&FIND.BidCollection{FIND.BidCollectionPublic}>(), ["find", "bids"])) + + account.storage.save(<-profile, to: Profile.storagePath) + account.link<&Profile.User{Profile.Public}>(Profile.publicPath, target: Profile.storagePath) + account.link<&{FungibleToken.Receiver}>(Profile.publicReceiverPath, target: Profile.storagePath) + } + + if account.storage.borrow<&Sender.Token>(from: Sender.storagePath) == nil { + account.storage.save(<- Sender.create(), to: Sender.storagePath) + } + + let token =account.storage.borrow<&Sender.Token>(from: Sender.storagePath)! + + + if type == "fusd" { + let vaultRef = account.storage.borrow<&FUSD.Vault>(from: /storage/fusdVault) ?? panic("Could not borrow reference to the fusdVault!") + let vault <- vaultRef.withdraw(amount: amount) + FIND.depositWithTagAndMessage(to: name, message: "", tag: tag, vault: <- vault, from: token) + return + } + + let vaultRef = account.storage.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) ?? panic("Could not borrow reference to the fusdVault!") + let vault <- vaultRef.withdraw(amount: amount) + FIND.depositWithTagAndMessage(to: name, message: "", tag: tag, vault: <- vault, from: token) + } } diff --git a/transactions/setup_fin_3_create_network.cdc b/transactions/setup_fin_3_create_network.cdc index 9ae28c1b..be6eab8e 100644 --- a/transactions/setup_fin_3_create_network.cdc +++ b/transactions/setup_fin_3_create_network.cdc @@ -6,20 +6,10 @@ import "FiatToken" transaction() { prepare(account: auth (BorrowValue, SaveValue, StorageCapabilities, IssueStorageCapabilityController, PublishCapability) &Account) { - let wallet=account.capabilities.get<&{FungibleToken.Receiver}>(/public/fusdReceiver) + let wallet=account.capabilities.get<&{FungibleToken.Receiver}>(/public/flowTokenReceiver) let adminClient=account.storage.borrow(from:Admin.AdminProxyStoragePath)! adminClient.setPublicEnabled(true) adminClient.setWallet(wallet) - - var usdcCap = account.capabilities.get<&{FungibleToken.Receiver}>(FiatToken.VaultReceiverPubPath) - if !usdcCap.check() { - account.storage.save( <-FiatToken.createEmptyVault(), to: FiatToken.VaultStoragePath) - let cap = account.capabilities.storage.issue<&FiatToken.Vault>(FiatToken.VaultStoragePath) - account.capabilities.publish(cap, at: FiatToken.VaultUUIDPubPath) - account.capabilities.publish(cap, at: FiatToken.VaultReceiverPubPath) - account.capabilities.publish(cap, at: FiatToken.VaultBalancePubPath) - } - } } diff --git a/transactions/setup_find_lease_market_2.cdc b/transactions/setup_find_lease_market_2.cdc index c9ba9691..4f5b3a91 100644 --- a/transactions/setup_find_lease_market_2.cdc +++ b/transactions/setup_find_lease_market_2.cdc @@ -3,6 +3,7 @@ import "FindMarket" import "FungibleToken" import "DapperUtilityCoin" import "FlowUtilityToken" +import "FlowToken" import "MetadataViews" transaction(tenantAddress: Address) { @@ -10,7 +11,7 @@ transaction(tenantAddress: Address) { let adminClient=account.storage.borrow(from: FindMarketAdmin.AdminProxyStoragePath)! let cut = [ - FindMarket.TenantRule( name:"standard ft", types:[Type<@DapperUtilityCoin.Vault>(), Type<@FlowUtilityToken.Vault>()], ruleType:"ft", allow:true) + FindMarket.TenantRule( name:"standard ft", types:[Type<@DapperUtilityCoin.Vault>(), Type<@FlowUtilityToken.Vault>(), Type<@FlowToken.Vault>()], ruleType:"ft", allow:true) ] let royalty = MetadataViews.Royalty( diff --git a/transactions/tenantsetLeaseOptionMarket.cdc b/transactions/tenantsetLeaseOptionMarket.cdc new file mode 100644 index 00000000..ede7c72a --- /dev/null +++ b/transactions/tenantsetLeaseOptionMarket.cdc @@ -0,0 +1,60 @@ +import "FindMarket" +import "FlowToken" +import "FindLeaseMarketSale" +import "FindLeaseMarketAuctionSoft" +import "FindLeaseMarketDirectOfferSoft" +import "MetadataViews" +import "FungibleToken" +import "FungibleTokenSwitchboard" + +transaction(nftName: String, nftType: String, cut: UFix64){ + prepare(account: auth(BorrowValue) &Account){ + + let defaultRules : [FindMarket.TenantRule] = [ + FindMarket.TenantRule( + name: "Flow", + types:[Type<@FlowToken.Vault>()], + ruleType: "ft", + allow:true + ), + FindMarket.TenantRule( + name: "Soft", + types:[Type<@FindLeaseMarketSale.SaleItem>(), + Type<@FindLeaseMarketAuctionSoft.SaleItem>(), + Type<@FindLeaseMarketDirectOfferSoft.SaleItem>() + ], + ruleType: "listing", + allow:true + ) + ] + + defaultRules.append( + FindMarket.TenantRule( + name: nftName, + types:[CompositeType(nftType)!], + ruleType: "nft", + allow:true + ) + ) + + var royalty : MetadataViews.Royalty? = nil + if cut != 0.0 { + royalty = MetadataViews.Royalty( + receiver: account.capabilities.get<&{FungibleToken.Receiver}>(FungibleTokenSwitchboard.ReceiverPublicPath), + cut: cut, + description: "tenant" + ) + } + + let saleItem = FindMarket.TenantSaleItem( + name: "Flow".concat(nftName).concat("Soft"), + cut: royalty, + rules: defaultRules, + status: "active" + ) + + let clientRef = account.storage.borrow(from: FindMarket.TenantClientStoragePath) ?? panic("Cannot borrow Tenant Client Reference.") + clientRef.setMarketOption(saleItem: saleItem) + } +} +