From 9fb5e4da67083fcb196b402c2c907342f3772de4 Mon Sep 17 00:00:00 2001 From: Alex Ni <12097569+nialexsan@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:04:34 -0500 Subject: [PATCH 1/5] update cadence to 1.0 --- .env.development | 3 +- .env.production | 1 + README.md | 5 +- cadence/contracts/Profile.cdc | 125 +++++++++++++----------- cadence/scripts/read-profile.cdc | 5 + cadence/transactions/create-profile.cdc | 15 +++ cadence/transactions/update-profile.cdc | 20 ++++ contexts/AuthContext.js | 48 ++------- flow.json | 18 ++-- flow/config.js | 5 +- next.config.js | 7 ++ package.json | 16 +-- 12 files changed, 145 insertions(+), 123 deletions(-) create mode 100644 cadence/scripts/read-profile.cdc create mode 100644 cadence/transactions/create-profile.cdc create mode 100644 cadence/transactions/update-profile.cdc diff --git a/.env.development b/.env.development index 5fdb85d..99ff9ef 100644 --- a/.env.development +++ b/.env.development @@ -1,3 +1,4 @@ -NEXT_PUBLIC_ACCESS_NODE_API=http://localhost:8080 +NEXT_PUBLIC_ACCESS_NODE_API=http://localhost:8888 NEXT_PUBLIC_DISCOVERY_WALLET=http://localhost:8701/fcl/authn NEXT_PUBLIC_CONTRACT_PROFILE=0xf8d6e0586b0a20c7 +NEXT_PUBLIC_FLOW_NETWORK=emulator \ No newline at end of file diff --git a/.env.production b/.env.production index b0563ba..beff51c 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,4 @@ NEXT_PUBLIC_ACCESS_NODE_API=https://rest-testnet.onflow.org NEXT_PUBLIC_DISCOVERY_WALLET=https://fcl-discovery.onflow.org/testnet/authn NEXT_PUBLIC_CONTRACT_PROFILE=0xba1132bc08f82fe2 +NEXT_PUBLIC_FLOW_NETWORK=testnet \ No newline at end of file diff --git a/README.md b/README.md index 5c740e0..65701a6 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,9 @@ npm run start Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start the emulator, deploy the contracts, followed by the development server: ```bash -flow emulator start --dev-wallet -flow project deploy --network emulator +flow emulator # run emulator +flow deploy # deploy smart contracts +flow dev-wallet # run dev wallet npm run dev # or start the server and open the app in a new browser tab diff --git a/cadence/contracts/Profile.cdc b/cadence/contracts/Profile.cdc index 832f395..b0ecd8d 100644 --- a/cadence/contracts/Profile.cdc +++ b/cadence/contracts/Profile.cdc @@ -69,11 +69,11 @@ This will lead to predictability in how applications can look up the data. transaction { let address: address - prepare(currentUser: AuthAccount) { + prepare(currentUser: auth(SaveValue, PublishCapability, IssueStorageCapabilityController) &Account) { self.address = currentUser.address if !Profile.check(self.address) { - currentUser.save(<- Profile.new(), to: Profile.privatePath) - currentUser.link<&Profile.Base{Profile.Public}>(Profile.publicPath, target: Profile.privatePath) + let profileCapability = currentUser.capabilities.storage.issue<&{Profile.Public}>(Profile.privatePath) + currentUser.capabilities.publish(profileCapability, at: Profile.publicPath) } } post { @@ -92,11 +92,12 @@ This will lead to predictability in how applications can look up the data. import Profile from 0xba1132bc08f82fe2 transaction { - prepare(currentUser: AuthAccount) { + prepare(currentUser: auth(SaveValue, PublishCapability, IssueStorageCapabilityController) &Account) { self.address = currentUser.address if !Profile.check(self.address) { currentUser.save(<- Profile.new(), to: Profile.privatePath) - currentUser.link<&Profile.Base{Profile.Public}>(Profile.publicPath, target: Profile.privatePath) + let profileCapability = currentUser.capabilities.storage.issue<&{Profile.Public}>(Profile.privatePath) + currentUser.capabilities.publish(profileCapability, at: Profile.publicPath) } } post { @@ -124,8 +125,9 @@ As the owner of a resource you can update the following: import Profile from 0xba1132bc08f82fe2 transaction(name: String) { - prepare(currentUser: AuthAccount) { + prepare(currentUser: auth(BorrowValue) &Account) { currentUser + .storage .borrow<&{Profile.Owner}>(from: Profile.privatePath)! .setName(name) } @@ -142,8 +144,9 @@ As the owner of a resource you can update the following: import Profile from 0xba1132bc08f82fe2 transaction(name: String) { - prepare(currentUser: AuthAccount) { + prepare(currentUser: auth(BorrowValue) &Account) { currentUser + .storage .borrow<&{Profile.Owner}>(from: Profile.privatePath)! .setName(name) } @@ -165,7 +168,7 @@ As the owner of a resource you can update the following: import Profile from 0xba1132bc08f82fe2 - pub fun main(address: Address): Profile.ReadOnly? { + access(all) fun main(address: Address): Profile.ReadOnly? { return Profile.read(address) } @@ -179,7 +182,7 @@ As the owner of a resource you can update the following: cadence: ` import Profile from 0xba1132bc08f82fe2 - pub fun main(address: Address): Profile.ReadOnly? { + access(all) fun main(address: Address): Profile.ReadOnly? { return Profile.read(address) } `, @@ -198,7 +201,7 @@ As the owner of a resource you can update the following: import Profile from 0xba1132bc08f82fe2 - pub fun main(addresses: [Address]): {Address: Profile.ReadOnly} { + access(all) fun main(addresses: [Address]): {Address: Profile.ReadOnly} { return Profile.readMultiple(addresses) } @@ -212,7 +215,7 @@ As the owner of a resource you can update the following: cadence: ` import Profile from 0xba1132bc08f82fe2 - pub fun main(addresses: [Address]): {Address: Profile.ReadOnly} { + access(all) fun main(addresses: [Address]): {Address: Profile.ReadOnly} { return Profile.readMultiple(addresses) } `, @@ -231,7 +234,7 @@ As the owner of a resource you can update the following: import Profile from 0xba1132bc08f82fe2 - pub fun main(address: Address): Bool { + access(all) fun main(address: Address): Bool { return Profile.check(address) } @@ -245,7 +248,7 @@ As the owner of a resource you can update the following: cadence: ` import Profile from 0xba1132bc08f82fe2 - pub fun main(address: Address): Bool { + access(all) fun main(address: Address): Bool { return Profile.check(address) } `, @@ -255,39 +258,39 @@ As the owner of a resource you can update the following: }) */ -pub contract Profile { - pub let publicPath: PublicPath - pub let privatePath: StoragePath - - pub resource interface Public { - pub fun getName(): String - pub fun getAvatar(): String - pub fun getColor(): String - pub fun getInfo(): String - pub fun asReadOnly(): Profile.ReadOnly +access(all) contract Profile { + access(all) let publicPath: PublicPath + access(all) let privatePath: StoragePath + + access(all) resource interface Public { + access(all) fun getName(): String + access(all) fun getAvatar(): String + access(all) fun getColor(): String + access(all) fun getInfo(): String + access(all) fun asReadOnly(): Profile.ReadOnly } - pub resource interface Owner { - pub fun getName(): String - pub fun getAvatar(): String - pub fun getColor(): String - pub fun getInfo(): String + access(all) resource interface Owner { + access(all) fun getName(): String + access(all) fun getAvatar(): String + access(all) fun getColor(): String + access(all) fun getInfo(): String - pub fun setName(_ name: String) { + access(all) fun setName(_ name: String) { pre { name.length <= 15: "Names must be under 15 characters long." } } - pub fun setAvatar(_ src: String) - pub fun setColor(_ color: String) - pub fun setInfo(_ info: String) { + access(all) fun setAvatar(_ src: String) + access(all) fun setColor(_ color: String) + access(all) fun setInfo(_ info: String) { pre { info.length <= 280: "Profile Info can at max be 280 characters long." } } } - pub resource Base: Owner, Public { + access(all) resource Base: Owner, Public { access(self) var name: String access(self) var avatar: String access(self) var color: String @@ -300,17 +303,17 @@ pub contract Profile { self.info = "" } - pub fun getName(): String { return self.name } - pub fun getAvatar(): String { return self.avatar } - pub fun getColor(): String {return self.color } - pub fun getInfo(): String { return self.info } + access(all) fun getName(): String { return self.name } + access(all) fun getAvatar(): String { return self.avatar } + access(all) fun getColor(): String {return self.color } + access(all) fun getInfo(): String { return self.info } - pub fun setName(_ name: String) { self.name = name } - pub fun setAvatar(_ src: String) { self.avatar = src } - pub fun setColor(_ color: String) { self.color = color } - pub fun setInfo(_ info: String) { self.info = info } + access(all) fun setName(_ name: String) { self.name = name } + access(all) fun setAvatar(_ src: String) { self.avatar = src } + access(all) fun setColor(_ color: String) { self.color = color } + access(all) fun setInfo(_ info: String) { self.info = info } - pub fun asReadOnly(): Profile.ReadOnly { + access(all) fun asReadOnly(): Profile.ReadOnly { return Profile.ReadOnly( address: self.owner?.address, name: self.getName(), @@ -321,12 +324,12 @@ pub contract Profile { } } - pub struct ReadOnly { - pub let address: Address? - pub let name: String - pub let avatar: String - pub let color: String - pub let info: String + access(all) struct ReadOnly { + access(all) let address: Address? + access(all) let name: String + access(all) let avatar: String + access(all) let color: String + access(all) let info: String init(address: Address?, name: String, avatar: String, color: String, info: String) { self.address = address @@ -337,31 +340,33 @@ pub contract Profile { } } - pub fun new(): @Profile.Base { + access(all) fun new(): @Profile.Base { return <- create Base() } - pub fun check(_ address: Address): Bool { + access(all) fun check(_ address: Address): Bool { return getAccount(address) - .getCapability<&{Profile.Public}>(Profile.publicPath) + .capabilities + .get<&{Profile.Public}>(Profile.publicPath) .check() } - pub fun fetch(_ address: Address): &{Profile.Public} { + access(all) fun fetch(_ address: Address): &{Profile.Public} { return getAccount(address) - .getCapability<&{Profile.Public}>(Profile.publicPath) + .capabilities + .get<&{Profile.Public}>(Profile.publicPath) .borrow()! } - pub fun read(_ address: Address): Profile.ReadOnly? { - if let profile = getAccount(address).getCapability<&{Profile.Public}>(Profile.publicPath).borrow() { + access(all) fun read(_ address: Address): Profile.ReadOnly? { + if let profile = getAccount(address).capabilities.get<&{Profile.Public}>(Profile.publicPath).borrow() { return profile.asReadOnly() } else { return nil } } - pub fun readMultiple(_ addresses: [Address]): {Address: Profile.ReadOnly} { + access(all) fun readMultiple(_ addresses: [Address]): {Address: Profile.ReadOnly} { let profiles: {Address: Profile.ReadOnly} = {} for address in addresses { let profile = Profile.read(address) @@ -377,11 +382,13 @@ pub contract Profile { self.publicPath = /public/profile self.privatePath = /storage/profile - self.account.save(<- self.new(), to: self.privatePath) - self.account.link<&Base{Public}>(self.publicPath, target: self.privatePath) + self.account.storage.save(<- self.new(), to: self.privatePath) + let profileCapability = self.account.capabilities.storage.issue<&{Public}>(self.privatePath) + self.account.capabilities.publish(profileCapability, at: self.publicPath) self.account - .borrow<&Base{Owner}>(from: self.privatePath)! + .storage + .borrow<&{Owner}>(from: self.privatePath)! .setName("qvvg") } } \ No newline at end of file diff --git a/cadence/scripts/read-profile.cdc b/cadence/scripts/read-profile.cdc new file mode 100644 index 0000000..2e908df --- /dev/null +++ b/cadence/scripts/read-profile.cdc @@ -0,0 +1,5 @@ +import "Profile" + +access(all) fun main(address: Address): Profile.ReadOnly? { + return Profile.read(address) +} diff --git a/cadence/transactions/create-profile.cdc b/cadence/transactions/create-profile.cdc new file mode 100644 index 0000000..ae624f7 --- /dev/null +++ b/cadence/transactions/create-profile.cdc @@ -0,0 +1,15 @@ +import "Profile" + +transaction { + prepare(account: auth(SaveValue, PublishCapability, IssueStorageCapabilityController) &Account) { + // Only initialize the account if it hasn't already been initialized + if (!Profile.check(account.address)) { + // This creates and stores the profile in the user's account + account.storage.save(<- Profile.new(), to: Profile.privatePath) + + // This creates the public capability that lets applications read the profile's info + let profileCapability = account.capabilities.storage.issue<&{Profile.Public}>(Profile.privatePath) + account.capabilities.publish(profileCapability, at: Profile.publicPath) + } + } +} diff --git a/cadence/transactions/update-profile.cdc b/cadence/transactions/update-profile.cdc new file mode 100644 index 0000000..218ff89 --- /dev/null +++ b/cadence/transactions/update-profile.cdc @@ -0,0 +1,20 @@ +import "Profile" + +transaction(name: String, color: String, info: String) { + prepare(account: auth(BorrowValue) &Account) { + account + .storage + .borrow<&{Profile.Owner}>(from: Profile.privatePath)! + .setName(name) + + account + .storage + .borrow<&{Profile.Owner}>(from: Profile.privatePath)! + .setInfo(info) + + account + .storage + .borrow<&{Profile.Owner}>(from: Profile.privatePath)! + .setColor(color) + } +} \ No newline at end of file diff --git a/contexts/AuthContext.js b/contexts/AuthContext.js index 74a83b8..91183ca 100644 --- a/contexts/AuthContext.js +++ b/contexts/AuthContext.js @@ -7,6 +7,9 @@ import { useState, } from "react"; import { useTransaction } from "./TransactionContext"; +import ReadProfileScript from "../cadence/scripts/read-profile.cdc" +import CreateProfileTransaction from "../cadence/transactions/create-profile.cdc" +import UpdateProfileTransaction from "../cadence/transactions/update-profile.cdc" export const AuthContext = createContext({}); @@ -23,13 +26,7 @@ export default function AuthProvider({ children }) { const loadProfile = useCallback(async () => { const profile = await fcl.query({ - cadence: ` - import Profile from 0xProfile - - pub fun main(address: Address): Profile.ReadOnly? { - return Profile.read(address) - } - `, + cadence: ReadProfileScript, args: (arg, t) => [arg(currentUser.addr, t.Address)], }); setProfile(profile ?? null); @@ -63,22 +60,7 @@ export default function AuthProvider({ children }) { initTransactionState(); const transactionId = await fcl.mutate({ - cadence: ` - import Profile from 0xProfile - - transaction { - prepare(account: AuthAccount) { - // Only initialize the account if it hasn't already been initialized - if (!Profile.check(account.address)) { - // This creates and stores the profile in the user's account - account.save(<- Profile.new(), to: Profile.privatePath) - - // This creates the public capability that lets applications read the profile's info - account.link<&Profile.Base{Profile.Public}>(Profile.publicPath, target: Profile.privatePath) - } - } - } - `, + cadence: CreateProfileTransaction, payer: fcl.authz, proposer: fcl.authz, authorizations: [fcl.authz], @@ -98,25 +80,7 @@ export default function AuthProvider({ children }) { initTransactionState(); const transactionId = await fcl.mutate({ - cadence: ` - import Profile from 0xProfile - - transaction(name: String, color: String, info: String) { - prepare(account: AuthAccount) { - account - .borrow<&Profile.Base{Profile.Owner}>(from: Profile.privatePath)! - .setName(name) - - account - .borrow<&Profile.Base{Profile.Owner}>(from: Profile.privatePath)! - .setInfo(info) - - account - .borrow<&Profile.Base{Profile.Owner}>(from: Profile.privatePath)! - .setColor(color) - } - } - `, + cadence: UpdateProfileTransaction, args: (arg, t) => [ arg(name, t.String), arg(color, t.String), diff --git a/flow.json b/flow.json index 03f1528..faeaa19 100644 --- a/flow.json +++ b/flow.json @@ -6,8 +6,8 @@ } }, "contracts": { - "Profile": "./cadence/contracts/Profile.cdc" - }, + "Profile": "./cadence/contracts/Profile.cdc" + }, "networks": { "emulator": "127.0.0.1:3569", "mainnet": "access.mainnet.nodes.onflow.org:9000", @@ -16,14 +16,14 @@ "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "key": "de98b6987469c7ba3692a2eb841c75becf66c65df19a0128398a20f0e5f9c812" + "key": "f8e188e8af0b8b414be59c4a1a15cc666c898fb34d94156e9b51e18bfde754a5" } }, "deployments": { - "emulator": { - "emulator-account": [ - "Profile" - ] - } - } + "emulator": { + "emulator-account": [ + "Profile" + ] + } + } } \ No newline at end of file diff --git a/flow/config.js b/flow/config.js index e2892a7..da34546 100644 --- a/flow/config.js +++ b/flow/config.js @@ -1,9 +1,10 @@ import { config } from "@onflow/fcl"; +import flowJSON from '../flow.json' config({ "app.detail.title": "Flow Next.js Quick Start", "app.detail.icon": "https://unavatar.io/twitter/muttonia", "accessNode.api": process.env.NEXT_PUBLIC_ACCESS_NODE_API, "discovery.wallet": process.env.NEXT_PUBLIC_DISCOVERY_WALLET, - "0xProfile": process.env.NEXT_PUBLIC_CONTRACT_PROFILE, // The account address where the smart contract lives -}) \ No newline at end of file + "flow.network": process.env.NEXT_PUBLIC_FLOW_NETWORK, +}).load({ flowJSON }) \ No newline at end of file diff --git a/next.config.js b/next.config.js index 0d60710..563a58f 100644 --- a/next.config.js +++ b/next.config.js @@ -1,3 +1,10 @@ module.exports = { reactStrictMode: true, + webpack: (config, _options) => { + config.module.rules.push({ + test: /\.cdc/, + type: "asset/source", + }) + return config + }, } diff --git a/package.json b/package.json index 12fbf83..cd8a012 100644 --- a/package.json +++ b/package.json @@ -8,15 +8,15 @@ "lint": "next lint" }, "dependencies": { - "@onflow/fcl": "^1.3.2", - "@picocss/pico": "^1.5.6", - "next": "^13.1.2", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "@onflow/fcl": "^1.12.3", + "@picocss/pico": "^2.0.6", + "next": "^15.0.3", + "react": "^18.3.1", + "react-dom": "^18.3.1" }, "devDependencies": { - "eslint": "8.4.1", - "eslint-config-next": "12.0.7", - "prettier": "^2.5.1" + "eslint": "^9.14.0", + "eslint-config-next": "^15.0.3", + "prettier": "^3.3.3" } } From e566d52b84207be1233713fe17eb3803929cf608 Mon Sep 17 00:00:00 2001 From: Alex Ni <12097569+nialexsan@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:10:25 -0500 Subject: [PATCH 2/5] revert pub key --- cadence/contracts/Profile.cdc | 2 +- cadence/transactions/update-profile.cdc | 2 +- flow.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cadence/contracts/Profile.cdc b/cadence/contracts/Profile.cdc index b0ecd8d..3d6d265 100644 --- a/cadence/contracts/Profile.cdc +++ b/cadence/contracts/Profile.cdc @@ -391,4 +391,4 @@ access(all) contract Profile { .borrow<&{Owner}>(from: self.privatePath)! .setName("qvvg") } -} \ No newline at end of file +} diff --git a/cadence/transactions/update-profile.cdc b/cadence/transactions/update-profile.cdc index 218ff89..e6a0603 100644 --- a/cadence/transactions/update-profile.cdc +++ b/cadence/transactions/update-profile.cdc @@ -17,4 +17,4 @@ transaction(name: String, color: String, info: String) { .borrow<&{Profile.Owner}>(from: Profile.privatePath)! .setColor(color) } -} \ No newline at end of file +} diff --git a/flow.json b/flow.json index faeaa19..b321b7d 100644 --- a/flow.json +++ b/flow.json @@ -16,7 +16,7 @@ "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "key": "f8e188e8af0b8b414be59c4a1a15cc666c898fb34d94156e9b51e18bfde754a5" + "key": "de98b6987469c7ba3692a2eb841c75becf66c65df19a0128398a20f0e5f9c812" } }, "deployments": { From 960e82e6ebf29797bf733a58d809b8155f00b776 Mon Sep 17 00:00:00 2001 From: Alex Ni <12097569+nialexsan@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:11:19 -0500 Subject: [PATCH 3/5] format --- .env.development | 2 +- .env.production | 2 +- flow/config.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.env.development b/.env.development index 99ff9ef..8eaeacf 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ NEXT_PUBLIC_ACCESS_NODE_API=http://localhost:8888 NEXT_PUBLIC_DISCOVERY_WALLET=http://localhost:8701/fcl/authn NEXT_PUBLIC_CONTRACT_PROFILE=0xf8d6e0586b0a20c7 -NEXT_PUBLIC_FLOW_NETWORK=emulator \ No newline at end of file +NEXT_PUBLIC_FLOW_NETWORK=emulator diff --git a/.env.production b/.env.production index beff51c..3ae7817 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,4 @@ NEXT_PUBLIC_ACCESS_NODE_API=https://rest-testnet.onflow.org NEXT_PUBLIC_DISCOVERY_WALLET=https://fcl-discovery.onflow.org/testnet/authn NEXT_PUBLIC_CONTRACT_PROFILE=0xba1132bc08f82fe2 -NEXT_PUBLIC_FLOW_NETWORK=testnet \ No newline at end of file +NEXT_PUBLIC_FLOW_NETWORK=testnet diff --git a/flow/config.js b/flow/config.js index da34546..b7e512a 100644 --- a/flow/config.js +++ b/flow/config.js @@ -7,4 +7,4 @@ config({ "accessNode.api": process.env.NEXT_PUBLIC_ACCESS_NODE_API, "discovery.wallet": process.env.NEXT_PUBLIC_DISCOVERY_WALLET, "flow.network": process.env.NEXT_PUBLIC_FLOW_NETWORK, -}).load({ flowJSON }) \ No newline at end of file +}).load({ flowJSON }) From 79677713bbdf57f7b76657f5adf30f8191dd9b97 Mon Sep 17 00:00:00 2001 From: Alex Ni <12097569+nialexsan@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:10:48 -0500 Subject: [PATCH 4/5] remove redundant profile address --- .env.development | 1 - .env.production | 1 - 2 files changed, 2 deletions(-) diff --git a/.env.development b/.env.development index 8eaeacf..cc18884 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,3 @@ NEXT_PUBLIC_ACCESS_NODE_API=http://localhost:8888 NEXT_PUBLIC_DISCOVERY_WALLET=http://localhost:8701/fcl/authn -NEXT_PUBLIC_CONTRACT_PROFILE=0xf8d6e0586b0a20c7 NEXT_PUBLIC_FLOW_NETWORK=emulator diff --git a/.env.production b/.env.production index 3ae7817..8b310cd 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,3 @@ NEXT_PUBLIC_ACCESS_NODE_API=https://rest-testnet.onflow.org NEXT_PUBLIC_DISCOVERY_WALLET=https://fcl-discovery.onflow.org/testnet/authn -NEXT_PUBLIC_CONTRACT_PROFILE=0xba1132bc08f82fe2 NEXT_PUBLIC_FLOW_NETWORK=testnet From e688ff534d6b9bfdac8ab1a6171401dd9a84e354 Mon Sep 17 00:00:00 2001 From: Alex Ni <12097569+nialexsan@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:14:23 -0500 Subject: [PATCH 5/5] add alias --- flow.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/flow.json b/flow.json index b321b7d..bbddd02 100644 --- a/flow.json +++ b/flow.json @@ -6,7 +6,13 @@ } }, "contracts": { - "Profile": "./cadence/contracts/Profile.cdc" + "Profile": { + "source": "./cadence/contracts/Profile.cdc", + "aliases": { + "emulator": "f8d6e0586b0a20c7", + "testnet": "ba1132bc08f82fe2" + } + } }, "networks": { "emulator": "127.0.0.1:3569",