Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making examples work out-of-the-box #224

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 85 additions & 57 deletions modules/client/examples/01-client/01-create-dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Comment on lines +42 to +43
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the intention with this comment? the code is already on lines 37-38


// 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove or uncomment


// 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the URL is more like ipfs://QmXhxqAneHFWr98Jqv96Pzm8pysfiLMcoyAuf8BQq6DK6m when you use the IPFS upload. Otherwise it can be any kind of URL

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
Expand Down
45 changes: 31 additions & 14 deletions modules/client/examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand All @@ -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.
Expand All @@ -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);