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

Wb3 15 add voting mechanism for anomaly #40

Closed
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
Binary file modified .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion api
11 changes: 9 additions & 2 deletions components/Gameplay/Stake/ApproxRewards.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import React, { useState, useEffect } from "react";
export default function ApproxRewards () {
return (
"This currently doesn't do anything due to compilation errors"
)
}

/*import React, { useState, useEffect } from "react";

import { useAddress } from "@thirdweb-dev/react";
import { SmartContract } from "@thirdweb-dev/sdk";
Expand All @@ -9,6 +15,7 @@ type Props = { helperContract: SmartContract<any>; };

export default function ApproxRewards ({ helperContract }: Props ) { // Calls contract to estimate the rewards owed to the authenticated player/user
const address = useAddress();
const addressString = address
const everyMillisecondAmount = parseInt(
(10_000_000_000_000 / 2.1).toFixed(0) // Assumes each block (on EVM) takes ~2.1 seconds to be mined. Begins when component isMounted
);
Expand Down Expand Up @@ -39,4 +46,4 @@ export default function ApproxRewards ({ helperContract }: Props ) { // Calls co
</b>
</p>
);
}
}*/
4 changes: 2 additions & 2 deletions components/Gameplay/Stake/CurrentGear.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function CurrentGear ({ // Shows the currently equipped planet ch
const address = useAddress();
const { data: planetNft } = useNFT(planetContract, 0); // Maps the data to the first planet nft (as for this version of the demo, we're only interacting with WASP-48b aka token id 1)
const [multitool, setMultitool] = useState<NFT>(); // If user has any multitools staked onto the helper contract. Previously <EditionDropMetadata>()
useEffect(() => {
/*useEffect(() => {
(async () => {
if (!address) return;
const p = ( await helperContract.call( // Connect to the helper contract
Expand All @@ -33,7 +33,7 @@ export default function CurrentGear ({ // Shows the currently equipped planet ch
setMultitool(multitoolMetadata);
}
})();
}, [address, helperContract, multitoolContract]); // Refresh this function if any of these values change. This component is reusable across multiple contracts (the contract addresses are defined in the page, not the component)
}, [address, helperContract, multitoolContract]); // Refresh this function if any of these values change. This component is reusable across multiple contracts (the contract addresses are defined in the page, not the component)*/

return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
Expand Down
8 changes: 6 additions & 2 deletions components/Gameplay/Stake/OwnedGear.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import React from "react";
export default function OwnedGear () {
return "This export is a stub for the original ownedGear component"
}

/*import React from "react";
import styles from '../../../styles/Staking-P2E/planetInteraction.module.css';

import { ThirdwebNftMedia, useAddress, useOwnedNFTs, Web3Button } from "@thirdweb-dev/react";
Expand Down Expand Up @@ -59,4 +63,4 @@ export default function OwnedGear ({ multitoolContract, helperContract }: Props)
</div>
</>
);
}
}*/
3 changes: 2 additions & 1 deletion components/Gameplay/Stake/Rewards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export default function Rewards({ helperContract, rewardsContract }: Props ) { /
Unclaimed: {" "}
<b>{unclaimedAmount && ethers.utils.formatUnits(unclaimedAmount)}</b>
</p>
<ApproxRewards helperContract={helperContract} />
<p>Approx rewards would go here</p>
{/*<ApproxRewards helperContract={helperContract} />*/}
<div className={styles.smallMargin}>
<Web3Button
contractAddress={HELPER_ADDRESS}
Expand Down
93 changes: 93 additions & 0 deletions components/Governance/Connections/AuthenticateAccount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { useState, useEffect } from "react";
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react";
import { useAddress } from "@thirdweb-dev/react";
import { Database } from "../../../utils/database.types";

type Profiles = Database['public']['Tables']['profiles']['Row'];

export default function AuthenticateWalletToDb () {
const session = useSession();
const supabase = useSupabaseClient();
const address = useAddress();

const [loading, setLoading] = useState(false);
const [userAddress, setUserAddress] = useState();
const [username, setUsername] = useState('');
const [updated_at, setUpdate_at] = useState();

async function getProfile () {
try {
setLoading(true);
if (!session) throw new Error('No user authenticated');
let { data, error, status } = await supabase
.from('profiles')
.select(`username, website, avatar_url, address`)
.eq('id', session?.user?.id)
.single()

if (error && status !== 406) {
throw error;
}

if (data) {
setUsername(data.username);
setUserAddress(data.address);
}
} catch (error) {
//alert('Error loading your user data');
console.log(error);
} finally {
setLoading(false);
}
}

useEffect(() => {
getProfile();
}, [session]);

async function updateProfile({
userAddress,
} : {
userAddress: Profiles['address']
}) {
try {
setLoading(true);
if (!session?.user) throw new Error('No user authenticated');
const updates = {
id: session?.user?.id,
address,
updated_at: new Date().toISOString(),
}
let { error } = await supabase.from('profiles').upsert(updates);
if (error) throw error;
alert('Off-chain PROFILE updated')
} catch (error) {
alert('Error updating your off-chain profile data');
console.log(error);
} finally {
setLoading(false);
}
}

if (loading) {
return (
"Loading"
);
}

if (!userAddress) {
return (
"Please authenticate via Metamask"
)
}

function updateProfileButton() {
updateProfile(userAddress);
}

return (
<div>
<button onClick={updateProfileButton}>Update profile</button>
</div>
)
}
21 changes: 14 additions & 7 deletions components/Lens/LensUser.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// Base imports / next
type Props = {};

export default function LensProfilePage ( {}: Props ) {
return "Stub"
}

/*/ Base imports / next
import React from "react";
import { useRouter } from "next/router";

Expand Down Expand Up @@ -45,7 +51,7 @@ export default function LensProfilePage ( {}: Props ) {

return (
<Flex w='100%'>
{/*<Sidebar />*/}
{/*<Sidebar />*/{/*
<center><Flex
pos="absolute"
top="50%"
Expand All @@ -55,7 +61,7 @@ export default function LensProfilePage ( {}: Props ) {
>
<div className={styles.profileContainer}>
<div className={styles.profileContentContainer}>
{/* @ts-ignore */}
{/* @ts-ignore */}{/*
{profileData?.profile?.coverPicture?.original?.url && (
<MediaRenderer
// @ts-ignore
Expand All @@ -64,7 +70,7 @@ export default function LensProfilePage ( {}: Props ) {
className={styles.coverImageContainer}
/>
)}
{/* @ts-ignore */}
{/* @ts-ignore */}{/*
{profileData?.profile?.picture?.original?.url && (
<MediaRenderer
// @ts-ignore
Expand Down Expand Up @@ -92,6 +98,7 @@ export default function LensProfilePage ( {}: Props ) {
</div></center>
</div>
</Flex></center>
</Flex>
);
}
</Flex>*/}
/*);
}
}*/
43 changes: 43 additions & 0 deletions contracts/extension 2/ContractMetadata.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

import "./interface/IContractMetadata.sol";

/**
* @title Contract Metadata
* @notice Thirdweb's `ContractMetadata` is a contract extension for any base contracts. It lets you set a metadata URI
* for you contract.
* Additionally, `ContractMetadata` is necessary for NFT contracts that want royalties to get distributed on OpenSea.
*/

abstract contract ContractMetadata is IContractMetadata {
/// @notice Returns the contract metadata URI.
string public override contractURI;

/**
* @notice Lets a contract admin set the URI for contract-level metadata.
* @dev Caller should be authorized to setup contractURI, e.g. contract admin.
* See {_canSetContractURI}.
* Emits {ContractURIUpdated Event}.
*
* @param _uri keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
*/
function setContractURI(string memory _uri) external override {
if (!_canSetContractURI()) {
revert("Not authorized");
}

_setupContractURI(_uri);
}

/// @dev Lets a contract admin set the URI for contract-level metadata.
function _setupContractURI(string memory _uri) internal {
string memory prevURI = contractURI;
contractURI = _uri;

emit ContractURIUpdated(prevURI, _uri);
}

/// @dev Returns whether contract metadata can be set in the given execution context.
function _canSetContractURI() internal view virtual returns (bool);
}
6 changes: 5 additions & 1 deletion contracts/planetProposal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,8 @@ contract PlanetProposal {
proposals[_proposalIndex].noVotes
);
}
}
}

/*
For use in testing voting on proposals from users on generated anomalies in play.skinetics.tech, working in the github/desci-md scripts
*/
5 changes: 5 additions & 0 deletions contracts/scripts/1_deploy_contract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Demo_Contract = artifacts.require("PlanetProposal");

module.exports = function(deployer) {
deployer.deploy(Demo_Contract);
};
19 changes: 19 additions & 0 deletions contracts/scripts/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
async function main() {
const [deployer] = await ethers.getSigners();

console.log("Deploying contracts with the account:", deployer.address);

console.log("Account balance:", (await deployer.getBalance()).toString());

const Token = await ethers.getContractFactory("Token");
const token = await Token.deploy();

console.log("Token address:", token.address);
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
14 changes: 14 additions & 0 deletions contracts/scripts/deployToGoerli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
async function main() {
const PlanetProposal = await ethers.getContractFactory("PlanetProposal");
const gasPrice = await PlanetProposal.signer.getGasPrice();
const estimatedGas = await PlanetProposal.signer.estimateGas(
PlanetProposal.getDeployTransaction()
);

const deploymentPrice = gasPrice.mul(estimatedGas);
const deployerBalance = await PlanetProposal.signer.getBalance();

if (Number(deployerBalance) < Number(deploymentPrice)) {
throw new Error("You don't have enough balance to deploy");
}
}
26 changes: 26 additions & 0 deletions contracts/scripts/deploy_voteContract.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import "dotenv/config";
import { MINERALS_ADDRESS } from "../../constants/contractAddresses";

const NETWORK = "goerli";
const GOERLI_PRIVATE_KEY = process.env.PRIVATE_KEY;
const sdk = ThirdwebSDK.fromPrivateKey(GOERLI_PRIVATE_KEY, NETWORK);

(async () => {
try {
const voteContractAddress = await sdk.deployer.deployVote({
name: "Star Sailors Metadata DAO",
voting_token_address: MINERALS_ADDRESS,
voting_delay_in_blocks: 0, // A user can vote on a proposal immediately after it is created
voting_period_in_blocks: 6570, // Each proposal can be voted on for 1 day after it is created
voting_quorum_fraction: 0,
proposal_token_threshold: 0,
});

console.log('Successfully deployed vote contract, address: ', voteContractAddress);
} catch (err) {
console.error("Failed to deploy vote contract, ", err);
}
})();

// voting address: 0xEee8EB851e3d528ef3b5C98CD41cb6F25c929415
39 changes: 39 additions & 0 deletions contracts/scripts/proposals.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import ethers from "hardhat";
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import "dotenv/config";
//import { MINERALS_ADDRESS } from "../../constants/contractAddresses";

const MINERALS_ADDRESS = '0xE938775F4ee4913470905885c9744C7FAD482991';
const NETWORK = "goerli";
const GOERLI_PRIVATE_KEY = process.env.PRIVATE_KEY;
// const sdk = ThirdwebSDK.fromPrivateKey(GOERLI_PRIVATE_KEY, NETWORK);
const sdk = ThirdwebSDK.fromPrivateKey('71cc30029998f3282069d43e547efd1894f51269e15a833815e5ed5f418a38e7', NETWORK);

(async () => {
try {
const vote = await sdk.getContract("0xd0F59Ed6EBf7f754fC3D5Fd7bb3181EBDeEd9E9d", "vote");
const token = await sdk.getContract("0xa791a3e0F2D2300Ee85eC7105Eee9E9E8eb57908", "token");

// Create a proposal to mint 420,000 new minerals to the treasury
const amount = 420_000;
const description = "Should the DAO mint an additional " + amount + " tokens into the treasury?";
const executions = [
{
toAddress: token.getAddress(),
nativeTokenValue: 0,
transactionData: token.encoder.encode("mintTo", [
vote.getAddress(),
ethers.utils.parseUnits(amount.toString(), 18),
]),
},
];

await vote.propose(description, executions);
console.log("✅ Successfully created proposal to mint tokens");

} catch (error) {
console.error("failed to create first proposal", error);
process.exit(1);
};
}
);
Loading