diff --git a/common/utils.go b/common/utils.go new file mode 100644 index 0000000..d7db527 --- /dev/null +++ b/common/utils.go @@ -0,0 +1,53 @@ +package common + +import ( + "fmt" + "reflect" + "regexp" +) + +var ( + placeholderNonFungibleToken = regexp.MustCompile(`"[^"\s]?.*NonFungibleToken(\.cdc)?"`) + placeholderExampleNFT = regexp.MustCompile(`"[^"\s].*ExampleNFT.cdc"`) + placeholderMetadataViews = regexp.MustCompile(`"[^"\s].*MetadataViews.cdc"`) + placeholderFungibleToken = regexp.MustCompile(`"[^"\s].*FungibleToken.cdc"`) +) + +type Replacer map[AddressName]*regexp.Regexp + +type AddressName string + +const ( + NonFungibleTokenAddr AddressName = "NonFungibleToken" +) + +func NewReplacer() Replacer { + xxx := map[AddressName]*regexp.Regexp{ + NonFungibleTokenAddr: placeholderNonFungibleToken, + } + return xxx +} + +func (r Replacer) ReplaceAddresses(code string, data interface{}) (string, error) { + + val := reflect.ValueOf(data) + if val.Kind() != reflect.Struct { + return "", fmt.Errorf("data must be a struct") + } + + var code1 = code + for i := 0; i < val.NumField(); i++ { + field := val.Type().Field(i) + fieldName := field.Name + fieldValue := val.Field(i).String() + + placeholder := AddressName(fieldName) + if r[placeholder] == nil { + return "", fmt.Errorf("no placeholder found for %s", placeholder) + } + + code1 = r[placeholder].ReplaceAllString(code1, "0x"+fieldValue) + fmt.Printf(`"%s %s"\n`, fieldName, fieldValue) + } + return code1, nil +} diff --git a/common/utils_test.go b/common/utils_test.go new file mode 100644 index 0000000..9816da7 --- /dev/null +++ b/common/utils_test.go @@ -0,0 +1,32 @@ +package common + +import ( + "github.com/dapperlabs/studio-platform-smart-contracts/pds" + "testing" +) + +func TestGetUserOwnedEditionToMomentMap_Transaction(t *testing.T) { + script, err := pds.Transaction.ReadFile("transactions/deploy/deploy-packNFT-with-auth.cdc") + if err != nil { + t.Fatal(err) + } + t.Log(string(script)) +} + +func TestGetUserOwnedEditionToMomentMap_Script(t *testing.T) { + script, err := pds.Scripts.ReadFile("scripts/packNFT/balance_packNFT.cdc") + if err != nil { + t.Fatal(err) + } + t.Log(string(script)) + dddd := NewReplacer() + aaa, err := dddd.ReplaceAddresses(string(script), struct { + NonFungibleToken string + }{ + "0x1", + }) + if err != nil { + t.Fatal(err) + } + t.Log(aaa) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..554be83 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/dapperlabs/studio-platform-smart-contracts + +go 1.20 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/pds/embed.go b/pds/embed.go new file mode 100644 index 0000000..eeea43f --- /dev/null +++ b/pds/embed.go @@ -0,0 +1,14 @@ +package pds + +import ( + "embed" +) + +//go:embed transactions/* +var Transactions embed.FS + +//go:embed scripts/* +var Scripts embed.FS + +//go:embed contracts/* +var Contracts embed.FS diff --git a/pds/transactions/dapperSport/link_providerCap_dapperSport.cdc b/pds/transactions/dapperSport/link_providerCap_dapperSport.cdc index c68b425..10d9b39 100644 --- a/pds/transactions/dapperSport/link_providerCap_dapperSport.cdc +++ b/pds/transactions/dapperSport/link_providerCap_dapperSport.cdc @@ -1,14 +1,16 @@ -import NonFungibleToken from 0x{{.NonFungibleToken}} -import {{.DapperSportContract}} from 0x{{.DapperSportAddress}} +import NonFungibleToken from "NonFungibleToken" +import DapperSport from "DapperSport" transaction(NFTProviderPath: PrivatePath) { - prepare(signer: AuthAccount) { - if signer.getCapability<&{NonFungibleToken.Provider}>(NFTProviderPath).check() { + prepare(signer: auth(Capabilities) &Account) { + if signer.capabilities.get<&{NonFungibleToken.Provider}>(at: NFTProviderPath).check() { return } + let cap = signer.capabilities.storage.issue<&{NonFungibleToken.Provider}>(target: DapperSport.CollectionStoragePath) + // This needs to be used to allow for PDS to withdraw - signer.link<&{NonFungibleToken.Provider}>( NFTProviderPath, target: {{.DapperSportContract}}.CollectionStoragePath) + signer.capabilities.publish(cap, at: NFTProviderPath) } } diff --git a/pds/transactions/flowTokens/transfer_flow_tokens_emulator.cdc b/pds/transactions/flowTokens/transfer_flow_tokens_emulator.cdc index 51b8c70..8b4e2e7 100644 --- a/pds/transactions/flowTokens/transfer_flow_tokens_emulator.cdc +++ b/pds/transactions/flowTokens/transfer_flow_tokens_emulator.cdc @@ -9,19 +9,24 @@ // This is required because the newly created account requires // balance for the deployment of the FiatToken contract. -import FungibleToken from 0xee82856bf20e2aa6 -import FlowToken from 0x0ae53cb6e3f42a79 +import FungibleToken from "FungibleToken" +import FlowToken from "FlowToken" +import FungibleTokenMetadataViews from "FungibleTokenMetadataViews" transaction(amount: UFix64, to: Address) { // The Vault resource that holds the tokens that are being transferred - let sentVault: @FungibleToken.Vault + /// FTVaultData metadata view for the token being used + let vaultData: FungibleTokenMetadataViews.FTVaultData + let sentVault: @{FungibleToken.Vault} - prepare(signer: AuthAccount) { + prepare(signer: auth(BorrowValue) &Account) { + self.vaultData = FlowToken.resolveContractView(resourceType: nil, viewType: Type()) as! FungibleTokenMetadataViews.FTVaultData? + ?? panic("ViewResolver does not resolve FTVaultData view") // Get a reference to he signer's stored vault - let vaultRef = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) - ?? panic("Could not borrow reference to the owner's Vault!") + let vaultRef = signer.storage.borrow(from: self.vaultData.storagePath) + ?? panic("Could not borrow reference to the owner's Vault!") // Withdraw tokens from the signer's stored vault self.sentVault <- vaultRef.withdraw(amount: amount) @@ -30,11 +35,10 @@ transaction(amount: UFix64, to: Address) { execute { // Get a reference to the recipient's Receiver let receiverRef = getAccount(to) - .getCapability(/public/flowTokenReceiver) - .borrow<&{FungibleToken.Receiver}>() - ?? panic("Could not borrow receiver reference to the recipient's Vault") + .capabilities.borrow<&{FungibleToken.Receiver}>(self.vaultData.receiverPath) + ?? panic("Could not borrow receiver reference to the recipient's Vault") // Deposit the withdrawn tokens in the recipient's receiver receiverRef.deposit(from: <-self.sentVault) } -} +} \ No newline at end of file diff --git a/pds/transactions/packNFT/create_new_packNFT_collection.cdc b/pds/transactions/packNFT/create_new_packNFT_collection.cdc index 8df1cd9..4c82fe9 100644 --- a/pds/transactions/packNFT/create_new_packNFT_collection.cdc +++ b/pds/transactions/packNFT/create_new_packNFT_collection.cdc @@ -2,15 +2,18 @@ import PackNFT from "PackNFT" import NonFungibleToken from "NonFungibleToken" transaction() { - prepare (issuer: AuthAccount) { + prepare (issuer: auth(Storage, Capabilities) &Account) { // Check if account already have a PackIssuer resource, if so destroy it - if issuer.borrow<&PackNFT.Collection>(from: PackNFT.CollectionStoragePath) == nil { - issuer.save(<- PackNFT.createEmptyCollection(), to: PackNFT.CollectionStoragePath); - issuer.link<&{NonFungibleToken.CollectionPublic}>(PackNFT.CollectionPublicPath, target: PackNFT.CollectionStoragePath) - ?? panic("Could not link Collection Pub Path"); - } + if issuer.storage.borrow<&PackNFT.Collection>(from: PackNFT.CollectionStoragePath) == nil { + let collection <- PackNFT.createEmptyCollection(nftType: Type<@PackNFT.NFT>()) + issuer.storage.save(<- collection, to: PackNFT.CollectionStoragePath); + issuer.capabilities.publish( + issuer.capabilities.storage.issue<&PackNFT.Collection>(PackNFT.CollectionStoragePath), + at: PackNFT.CollectionPublicPath + ) + } } } diff --git a/pds/transactions/pds/create_distribution.cdc b/pds/transactions/pds/create_distribution.cdc index c076184..3a5193e 100644 --- a/pds/transactions/pds/create_distribution.cdc +++ b/pds/transactions/pds/create_distribution.cdc @@ -1,17 +1,17 @@ import PDS from "PDS" -import {{.PackNFTName}} from "PackNFT" +import PackNFT from "PackNFT" import IPackNFT from "IPackNFT" import NonFungibleToken from "NonFungibleToken" -transaction(title: String, metadata: {String: String}) { +transaction(NFTProviderPathIdentifier: String, title: String, metadata: {String: String}) { prepare (issuer: auth(BorrowValue, Capabilities) &Account) { let i = issuer.storage.borrow(from: PDS.PackIssuerStoragePath) ?? panic ("issuer does not have PackIssuer resource") // issuer must have a PackNFT collection - let withdrawCap = issuer.capabilities.storage.issue(StoragePath(identifier: "exampleNFTCollection")!); - let operatorCap = issuer.capabilities.storage.issue({{.PackNFTName}}.OperatorStoragePath); + let withdrawCap = issuer.capabilities.storage.issue(StoragePath(identifier: NFTProviderPathIdentifier)!); + let operatorCap = issuer.capabilities.storage.issue(PackNFT.OperatorStoragePath); assert(withdrawCap.check(), message: "cannot borrow withdraw capability") assert(operatorCap.check(), message: "cannot borrow operator capability") diff --git a/pds/transactions/pds/mint_packNFT.cdc b/pds/transactions/pds/mint_packNFT.cdc index c009cd7..812928f 100644 --- a/pds/transactions/pds/mint_packNFT.cdc +++ b/pds/transactions/pds/mint_packNFT.cdc @@ -1,11 +1,11 @@ import PDS from "PDS" -import {{.PackNFTName}} from "PackNFT" +import PackNFT from "PackNFT" import NonFungibleToken from "NonFungibleToken" transaction (distId: UInt64, commitHashes: [String], issuer: Address ) { prepare(pds: auth(BorrowValue) &Account) { let recvAcct = getAccount(issuer) - let recv = recvAcct.capabilities.borrow<&{NonFungibleToken.CollectionPublic}>({{.PackNFTName}}.CollectionPublicPath) + let recv = recvAcct.capabilities.borrow<&{NonFungibleToken.CollectionPublic}>(PackNFT.CollectionPublicPath) ?? panic("Unable to borrow Collection Public reference for recipient") let cap = pds.storage.borrow<&PDS.DistributionManager>(from: PDS.DistManagerStoragePath) ?? panic("pds does not have Dist manager") diff --git a/pds/transactions/pds/settle.cdc b/pds/transactions/pds/settle.cdc index d0c4a0c..5862402 100644 --- a/pds/transactions/pds/settle.cdc +++ b/pds/transactions/pds/settle.cdc @@ -1,14 +1,14 @@ import PDS from "PDS" import ExampleNFT from "ExampleNFT" -transaction (distId: UInt64, nftIDs: [UInt64]) { +transaction (NFTProviderPath: String, distId: UInt64, nftIDs: [UInt64]) { prepare(pds: auth(BorrowValue) &Account) { let cap = pds.storage.borrow<&PDS.DistributionManager>(from: PDS.DistManagerStoragePath) ?? panic("pds does not have Dist manager") cap.withdraw( distId: distId, nftIDs: nftIDs, - escrowCollectionPublic: PublicPath(identifier: "exampleNFTCollection")!, + escrowCollectionPublic: PublicPath(identifier: NFTProviderPath)!, ) } }