diff --git a/modules/client/examples/01-client/01-create-dao.ts b/modules/client/examples/01-client/01-create-dao.ts index 654571b41..8dca322bd 100644 --- a/modules/client/examples/01-client/01-create-dao.ts +++ b/modules/client/examples/01-client/01-create-dao.ts @@ -33,68 +33,96 @@ const metadata: DaoMetadata = { }], }; -// Through pinning the metadata in IPFS, we can get the IPFS URI. You can read more about it here: https://docs.ipfs.tech/how-to/pin-files/ -const metadataUri = await client.methods.pinMetadata(metadata); - -// You need at least one plugin in order to create a DAO. In this example, we'll use the TokenVoting plugin, but feel free to install whichever one best suites your needs. You can find resources on how to do this in the plugin sections. -// These would be the plugin params if you need to mint a new token for the DAO to enable TokenVoting. -const tokenVotingPluginInstallParams: TokenVotingPluginInstall = { - votingSettings: { - minDuration: 60 * 60 * 24 * 2, // seconds - minParticipation: 0.25, // 25% - supportThreshold: 0.5, // 50% - minProposerVotingPower: BigInt("5000"), // default 0 - votingMode: VotingMode.EARLY_EXECUTION, // default is STANDARD. other options: EARLY_EXECUTION, VOTE_REPLACEMENT - }, - newToken: { - name: "Token", // the name of your token - symbol: "TOK", // the symbol for your token. shouldn't be more than 5 letters - decimals: 18, // the number of decimals your token uses - minter: "0x...", // optional. if you don't define any, we'll use the standard OZ ERC20 contract. Otherwise, you can define your own token minter contract address. - balances: [ - { // Defines the initial balances of the new token - address: "0x2371238740123847102983471022", // address of the account to receive the newly minted tokens - balance: BigInt(10), // amount of tokens that address should receive - }, - ], - }, -}; +const main = async () => { + // Through pinning the metadata in IPFS, we can get the IPFS URI. You can read more about it here: https://docs.ipfs.tech/how-to/pin-files/ + const metadataUri = await client.methods.pinMetadata(metadata); -// Creates a TokenVoting plugin client with the parameteres defined above (with an existing token). -const tokenVotingInstallItem = TokenVotingClient.encoding - .getPluginInstallItem(tokenVotingPluginInstallParams); + console.log("Creating DAO..."); -const createDaoParams: CreateDaoParams = { - metadataUri, - ensSubdomain: "my-org", // my-org.dao.eth - plugins: [tokenVotingInstallItem], // plugin array cannot be empty or the transaction will fail. you need at least one governance mechanism to create your DAO. -}; + // Through pinning the metadata in IPFS, we can get the IPFS URI. You can read more about it here: https://docs.ipfs.tech/how-to/pin-files/ + // const metadataUri = await client.methods.pinMetadata(metadata); + + // You need at least one plugin in order to create a DAO. In this example, we'll use the TokenVoting plugin, but feel free to install whichever one best suites your needs. You can find resources on how to do this in the plugin sections. + // These would be the plugin params if you need to mint a new token for the DAO to enable TokenVoting. + const tokenVotingPluginInstallParams: TokenVotingPluginInstall = { + votingSettings: { + minDuration: 60 * 60 * 24 * 2, // seconds + minParticipation: 0.25, // 25% + supportThreshold: 0.5, // 50% + minProposerVotingPower: BigInt("5000"), // default 0 + votingMode: VotingMode.EARLY_EXECUTION, // default is STANDARD. other options: EARLY_EXECUTION, VOTE_REPLACEMENT + }, + newToken: { + name: "My DAO", // the name of your token + symbol: "DAOTOKEN", // the symbol for your token. shouldn't be more than 5 letters + decimals: 18, // the number of decimals your token uses + // minter: "0x...", // optional. if you don't define any, we'll use the standard OZ ERC20 contract. Otherwise, you can define your own token minter contract address. + balances: [ + { + // Defines the initial balances of the new token + address: await context.signer.getAddress(), // address of the account to receive the newly minted tokens + balance: BigInt(10), // amount of tokens that address should receive + }, + ], + }, + }; + + // Creates a TokenVoting plugin client with the parameteres defined above (with an existing token). + const tokenVotingInstallItem = + TokenVotingClient.encoding.getPluginInstallItem( + tokenVotingPluginInstallParams, + context.network + ); + + // console.log('tokenVotingInstallItem', tokenVotingInstallItem); -// Estimate how much gas the transaction will cost. -const estimatedGas: GasFeeEstimation = await client.estimation.createDao( - createDaoParams, -); -console.log({ avg: estimatedGas.average, maximum: estimatedGas.max }); - -// Create the DAO. -const steps = client.methods.createDao(createDaoParams); - -for await (const step of steps) { - try { - switch (step.key) { - case DaoCreationSteps.CREATING: - console.log({ txHash: step.txHash }); - break; - case DaoCreationSteps.DONE: - console.log({ - daoAddress: step.address, - pluginAddresses: step.pluginAddresses, - }); - break; + const createDaoParams: CreateDaoParams = { + metadataUri, // : `https://dao.mydao.com/metadata.json`, // the URI of the metadata file + ensSubdomain: "my-org", // my-org.dao.eth + plugins: [tokenVotingInstallItem], // plugin array cannot be empty or the transaction will fail. you need at least one governance mechanism to create your DAO. + }; + + // Estimate how much gas the transaction will cost. + const estimatedGas: GasFeeEstimation = await client.estimation.createDao( + createDaoParams + ); + console.log("estimate dao create", { + avg: estimatedGas.average, + maximum: estimatedGas.max, + }); + + // Create the DAO. + const steps = client.methods.createDao(createDaoParams); + + for await (const step of steps) { + try { + switch (step.key) { + case DaoCreationSteps.CREATING: + console.log("dao deploying...", { txHash: step.txHash }); + break; + case DaoCreationSteps.DONE: + console.log("dao created", { + daoAddress: step.address, + pluginAddresses: step.pluginAddresses, + }); + break; + } + } catch (err) { + console.error(err); } - } catch (err) { - console.error(err); } +}; + +// if running in shell, execute the main function +if (require.main === module) { + main() + .then(() => process.exit(0)) + .catch((error) => { + // console.error(error.message); + // if (process.env.DEBUG) + console.error(error); + process.exit(1); + }); } /* MARKDOWN diff --git a/modules/client/examples/index.ts b/modules/client/examples/index.ts index fa601b1bf..5123d550e 100644 --- a/modules/client/examples/index.ts +++ b/modules/client/examples/index.ts @@ -32,35 +32,50 @@ Then, you'll want to set up the Aragon OSx SDK context within your application t However, so you're not setting it up multiple times, we recommend you set it up as a [context hook](https://www.freecodecamp.org/news/react-context-for-beginners/) within Javascript application if you're using a framework like React, Vue, or other, or within the entry file of your app. */ +import "dotenv/config"; + import { Wallet } from "@ethersproject/wallet"; import { Context, ContextParams } from "@aragon/sdk-client"; // Set up your IPFS API key. You can get one either by running a local node or by using a service like Infura or Alechmy. // Make sure to always keep these private in a file that is not committed to your public repository. -export const IPFS_API_KEY: string = "ipfs-api-key"; +export const ARAGON_IPFS_API_KEY: string = "ipfs-api-key"; + +if (!process.env.MNEMONIC) { + // generate a new mnemonic + const mnemonic = Wallet.createRandom().mnemonic.phrase; + console.log(`Generated new mnemonic: ${mnemonic}. Save it!`); + process.exit(0); +} + +const mnemonic = process.env.MNEMONIC; + +export const wallet = Wallet.fromMnemonic(mnemonic); // OPTION A: The simplest ContextParams you can have is this. This uses our default values and should work perfectly within your product. const minimalContextParams: ContextParams = { // Choose the network you want to use. You can use "goerli" (Ethereum) or "maticmum" (Polygon) for testing, or "mainnet" (Ethereum) and "polygon" (Polygon) for mainnet. - network: "mainnet", - web3Providers: "https://eth.llamarpc.com", + network: "goerli", + web3Providers: ["https://rpc.ankr.com/eth_goerli"], + // This is the signer account who will be signing transactions for your app. You can use also use a specific account where you have funds, through passing it `new Wallet("your-wallets-private-key")` or pass it in dynamically when someone connects their wallet to your dApp. - signer: Wallet.createRandom(), + signer: wallet, }; // OPTION B: For a more advanced option, you can use the following ContextParams. This will allow you to use your own custom values if desired. -export const contextParams: ContextParams = { +export const fullContextParams: ContextParams = { // Choose the network you want to use. You can use "goerli" (Ethereum) or "maticmum" (Mumbai) for testing, or "mainnet" (Ethereum) and "polygon" (Polygon) for mainnet. network: "goerli", // This is the account that will be signing transactions for your app. You can use also use a specific account where you have funds, through passing it `new Wallet("your-wallets-private-key")` or pass it in dynamically when someone connects their wallet to your dApp. - signer: Wallet.createRandom(), + signer: wallet, + // Optional on "rinkeby", "arbitrum-rinkeby" or "mumbai" // Pass the address of the `DaoFactory` contract you want to use. You can find it here based on your chain of choice: https://github.com/aragon/core/blob/develop/active_contracts.json // Optional. Leave it empty to use Aragon's DAO Factory contract and claim a dao.eth subdomain - daoFactoryAddress: "0x1234381072385710239847120734123847123", + // daoFactoryAddress: "", // Optional. Pass the address of the ensRegistry for networks other than Mainnet or Goerli. // It will default to the registry deployed by Aragon. You can check them here: https://github.com/aragon/osx/blob/develop/active_contracts.json - ensRegistryAddress: "0x1234381072385710239847120734123847123", + // ensRegistryAddress: "", // Choose your Web3 provider: Cloudfare, Infura, Alchemy, etc. // Remember to change the list of providers if a different network is selected web3Providers: ["https://rpc.ankr.com/eth_goerli"], @@ -69,7 +84,7 @@ export const contextParams: ContextParams = { ipfsNodes: [ { url: "https://test.ipfs.aragon.network/api/v0", - headers: { "X-API-KEY": IPFS_API_KEY || "" }, + headers: { "X-API-KEY": ARAGON_IPFS_API_KEY || "" }, }, ], // Optional. By default it will use Aragon's provided endpoints. @@ -81,16 +96,18 @@ export const contextParams: ContextParams = { ], }; - // After defining the context parameters, you'll use them to instantiate the Aragon SDK context -export const context: Context = new Context(contextParams); // or minimalContextParams // Instantiate the Aragon SDK context -export const minimalContext: Context = new Context(minimalContextParams); +export const context: Context = new Context(minimalContextParams); // or fullContextParams /* MARKDOWN Update the context with new parameters if you wish to throughout your app. */ context.set({ network: 1 }); -context.set({ signer: new Wallet("private key") }); // if you're using wagmi library, you can also get the signer through their [`useSigner` method](https://wagmi.sh/react/hooks/useSigner) inside a `useEffect` hook. -context.set(contextParams); + +// if you're using wagmi library, you can also get the signer through their [`useSigner` method](https://wagmi.sh/react/hooks/useSigner) inside a `useEffect` hook. +// context.set({ signer: Wallet.fromMnemonic(mnemonic) }); + +context.set(minimalContextParams); +