Skip to content

Commit

Permalink
🔬🧪 ↝ Merge pull request #27 from Signal-K/wb3-5-take-user-inputs-for-…
Browse files Browse the repository at this point in the history
…minting-via-flask

🔬🦺 ↝ Getting user inputs being sent between Flask/Deepnote, Unity, Supabase & the goerli testnet for EVM
  • Loading branch information
Gizmotronn authored Jan 21, 2023
2 parents 2d303d4 + 9f3aae4 commit ef651f5
Show file tree
Hide file tree
Showing 107 changed files with 1,935 additions and 22,359 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "container/lib/forge-std"]
path = container/lib/forge-std
url = https://github.com/foundry-rs/forge-std.git
[submodule "Server/client"]
path = Server/client
url = https://github.com/signal-k/client
Binary file added Classify/contracts/.PlanetHelper.sol.swp
Binary file not shown.
83 changes: 83 additions & 0 deletions Classify/contracts/PlanetHelper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;

// Import thirdweb contracts
import "@thirdweb-dev/contracts/drop/DropERC1155.sol"; // For my collection of Pickaxes
import "@thirdweb-dev/contracts/token/TokenERC20.sol"; // For my ERC-20 Token contract
import "@thirdweb-dev/contracts/openzeppelin-presets/utils/ERC1155/ERC1155Holder.sol"; // For my ERC-1155 Receiver contract
/* Extra metadata/tags contracts (no function)
import "@thirdweb-dev/contracts/drop/ERC721.sol";
import "@thirdweb-dev/contracts/drop/ERC20.sol";
import "@thirdweb-dev/contracts/token/Token721.sol";*/


// OpenZeppelin (ReentrancyGuard)
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract PlanetHelper is ReentrancyGuard, ERC1155Holder {
DropERC1155 public immutable planetNFTCollection; // Edition drop for the planets (terminology & game item may change around...e.g. PlanetHelper or planetNFTCollection may become a pickaxe/mining bot)
TokenERC20 public immutable rewardsToken; // Starting off with rewarding Minerals to the user - more resource types will be added

// Metadata deeplinks (taken out of constructor)
string public classificationContractArchive = 'goerli/0xed6e837Fda815FBf78E8E7266482c5Be80bC4bF9'; // Archived version of the classification proposal contract on the Mumbai testnet. Used for archival purposes
string public jupyterNotebook = 'https://deepnote.com/workspace/star-sailors-49d2efda-376f-4329-9618-7f871ba16007/project/Star-Sailors-Light-Curve-Plot-b4c251b4-c11a-481e-8206-c29934eb75da/notebook/Light%20Curve%20Demo-0c60a045940145ba950f2c0e51cac7c1'; // Deeplink to a copy of the Deepnote notebook
string public jupyterNftTagId = 'goerli/0xdf35Bb26d9AAD05EeC5183c6288f13c0136A7b43/1'; // Deep link to a goerli NFT with some metadata relevant to the jupyterNotebook
// This contract is a 'helper', aka multitool provider for your planets in the Star Sailors game. Using this contract, you'll be able to perform different actions on the planets in your inventory, such as mining, building & customising the terrain and life. More documentation is available on Notion at https://skinetics.notion.site/421c898e3583496bb9dc950e3150b8d0?v=db85a572b6c5409e998451318d6b5187 and on our Github -> https://github.com/signal-k/sytizen

constructor(DropERC1155 planetNFTCollectionAddress, TokenERC20 mineralsTokenAddress) {
planetNFTCollection = planetNFTCollectionAddress;
rewardsToken = mineralsTokenAddress; // For this helper function, minerals will be the primary resource (later this trait on the planet nft will determine whcib of the Helpers is called (each helper will have different rewards))
}

struct MapValue {
bool isData; // Is being staked?
uint256 value; // Token id being staked
}

// Map the player address to their current "helper" item
mapping (address => MapValue) public playerHelper; // TokenID of helper (type of mining/gathering tool) is the reward multiplier. This here lists the type of tool the user is using
mapping (address => MapValue) public playerLastUpdate; // Map the address to the time they last claimed/staked/withdrew. Default state is null -> not in the mapping. { is there a value, timestamp of last action}

function stake (uint256 _tokenId) external nonReentrant {
require (planetNFTCollection.balanceOf(msg.sender, _tokenId) >= 1, "You must have at least one planet to stake");
if (playerHelper[msg.sender].isData) { // If the user has a helper that is already staked : send it back to address (unstake)
planetNFTCollection.safeTransferFrom(address(this), msg.sender, playerHelper[msg.sender].value, 1, "Returning your old helper item");
}

uint256 reward = calculateRewards(msg.sender); // Calculate the rewards owed to the address
rewardsToken.transfer(msg.sender, reward);

planetNFTCollection.safeTransferFrom(msg.sender, address(this), _tokenId, 1, "Staking your planet"); // Actual statement that transfers the nft from the user to this staking contract to begin staking
playerHelper[msg.sender].value = _tokenId; // Update the mapping for the helper NFT once it's been staked
playerHelper[msg.sender].isData = true;
playerLastUpdate[msg.sender].value = block.timestamp; // Update the mapping for the playerLastUpdate tag. It's set to the current time (and we can use that and the state of the nft to calculate rewards)
playerLastUpdate[msg.sender].isData = true;
}

function withdraw () external nonReentrant {
require(playerHelper[msg.sender].isData, "You do not have a helper staked to withdraw"); // The user can't execute this function if they aren't staking anything
uint256 reward = calculateRewards(msg.sender);
rewardsToken.transfer(msg.sender, reward);
planetNFTCollection.safeTransferFrom(address(this), msg.sender, playerHelper[msg.sender].value, 1, "Transferring your previously staked nft to your wallet");
playerHelper[msg.sender].isData = false; // Update the helper mapping
playerLastUpdate[msg.sender].isData = true; // There's been a new update -> so update the mapping
playerLastUpdate[msg.sender].value = block.timestamp;
}

function claim () external nonReentrant {
uint256 reward = calculateRewards(msg.sender);
rewardsToken.transfer(msg.sender, reward);
playerLastUpdate[msg.sender].isData = true; // Update mappings for last event for player
playerLastUpdate[msg.sender].value = block.timestamp;
}

function calculateRewards (address _player) public view returns (uint256 _rewards) { // 20,000,000 rewards/minerals per block. Uses block.timestamp & playerLastUpdate. Requires the player to have staked a helper item
if (!playerLastUpdate[_player].isData || !playerHelper[_player].isData) { // Either nothing is being staked, or the player hasn't ever staked/edited their stake items
return 0; // No rewards are owed to the player/address
}

uint256 timeDifference = block.timestamp - playerLastUpdate[_player].value; // Time difference between now and when the last action on their helper occured
uint256 rewards = timeDifference * 10_000_000_000_000 * (playerHelper[_player].value + 1); // If there is a higher level helper (see the evolution stage), the reward is greater
return rewards;
}
}
5 changes: 5 additions & 0 deletions Classify/contracts/contractAddresses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const HELPER_ADDRESS = '0xcf05AB21cAa609c81D6DfF435F0F8808A05EA264'; // custom contract
// 0xcf05AB21cAa609c81D6DfF435F0F8808A05EA264 is deployed from the correct wallet, but has a problem - it points to the Planets contract as the multitools contract (i.e. the planets are both the required nft and the nft that is being staked. This could be implemented in future...but for now we need to fix this. So I've redeployed it on a new address (see above line) with the correct pointer). See https://skinetics.notion.site/Planet-Mining-multitool-8310fa1cd188440688bbcc19692b3b67. Derived from https://thirdweb.com/0xCdc5929e1158F7f0B320e3B942528E6998D8b25c/PlanetHelper/1.0.1?via=/goerli/0xcf05AB21cAa609c81D6DfF435F0F8808A05EA264
export const MULTITOOLS_ADDRESS = '0xF846D262EeBAFbfA79017b43aBb0251F740a0619';
export const PLANETS_ADDRESS = '0xdf35Bb26d9AAD05EeC5183c6288f13c0136A7b43'; // edition drop (erc1155)
export const MINERALS_ADDRESS = '0xE938775F4ee4913470905885c9744C7FAD482991';
2 changes: 1 addition & 1 deletion Classify/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
version: '0.8.9',
version: '0.8.11',
defaultNetwork: 'goerli',
networks: {
hardhat: {},
Expand Down
3 changes: 2 additions & 1 deletion Classify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
"release": "npx thirdweb@latest release"
},
"devDependencies": {
"hardhat": "^2.10.1"
"hardhat": "^2.12.6"
},
"dependencies": {
"@openzeppelin/contracts-upgradeable": "^4.8.1",
"@thirdweb-dev/contracts": "^3",
"dotenv": "^16.0.3"
}
Expand Down
23 changes: 14 additions & 9 deletions Classify/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@
"@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.0"
"@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.0"

"@openzeppelin/contracts-upgradeable@^4.8.1":
version "4.8.1"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.1.tgz#363f7dd08f25f8f77e16d374350c3d6b43340a7a"
integrity sha512-1wTv+20lNiC0R07jyIAbHU7TNHKRwGiTGRfiNnA8jOWjKT98g5OgLpYWOi40Vgpk8SPLA9EvfJAbAeIyVn+7Bw==

"@scure/base@~1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
Expand Down Expand Up @@ -1230,10 +1235,10 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==

hardhat@^2.10.1:
version "2.12.4"
resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.4.tgz#e539ba58bee9ba1a1ced823bfdcec0b3c5a3e70f"
integrity sha512-rc9S2U/4M+77LxW1Kg7oqMMmjl81tzn5rNFARhbXKUA1am/nhfMJEujOjuKvt+ZGMiZ11PYSe8gyIpB/aRNDgw==
hardhat@^2.12.6:
version "2.12.6"
resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.6.tgz#ea3c058bbd81850867389d10f76037cfa52a0019"
integrity sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA==
dependencies:
"@ethersproject/abi" "^5.1.2"
"@metamask/eth-sig-util" "^4.0.0"
Expand Down Expand Up @@ -1282,7 +1287,7 @@ hardhat@^2.10.1:
source-map-support "^0.5.13"
stacktrace-parser "^0.1.10"
tsort "0.0.1"
undici "^5.4.0"
undici "^5.14.0"
uuid "^8.3.2"
ws "^7.4.6"

Expand Down Expand Up @@ -2090,10 +2095,10 @@ type-fest@^0.7.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48"
integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==

undici@^5.4.0:
version "5.14.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.14.0.tgz#1169d0cdee06a4ffdd30810f6228d57998884d00"
integrity sha512-yJlHYw6yXPPsuOH0x2Ib1Km61vu4hLiRRQoafs+WUgX1vO64vgnxiCEN9dpIrhZyHFsai3F0AEj4P9zy19enEQ==
undici@^5.14.0:
version "5.15.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.15.0.tgz#cb8437c43718673a8be59df0fdd4856ff6689283"
integrity sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g==
dependencies:
busboy "^1.6.0"

Expand Down
50 changes: 25 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# sytizen-unity
[![.github/workflows/moralis.yml](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml/badge.svg?branch=ansible)](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml) <br />
Citizen Science (Sci-tizen) visualisation in the Unity.com engine


Check out our compass [here](http://ar.skinetics.tech/stellarios/compass) for more information about this product

# Contracts
<a href="https://thirdweb.com/goerli/0xCcaA1ABA77Bae6296D386C2F130c46FEc3E5A004?utm_source=contract_badge" target="_blank">
<img width="200" height="45" src="https://badges.thirdweb.com/contract?address=0xCcaA1ABA77Bae6296D386C2F130c46FEc3E5A004&theme=dark&chainId=5" alt="View contract" />
</a>

<!--
Move `/server` into a separate submodule (or `styizen` into a submodule in another repo)
Add react config (for frontend framework) to react, then move it into `signal-k/polygon`
-->

## Trader branch
This branch contains a connection between Supabase (our current hosting platform for this backend) and the rest our our Notebooks & API. Everything else has been stripped out of this branch.

Run `python3 -m venv .venv` to get started.

Note: Start integrating in API from signal-k/polygon

### Planti branch
Stripping everything out (e.g. `Ansible`/`Generator`) and just leaving the initial dashboard/game frontend. We'll merge it back with `Trader` later
[![.github/workflows/moralis.yml](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml/badge.svg?branch=ansible)](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml)
[![Node.js CI](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml/badge.svg)](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml)
[![Node.js CI](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml/badge.svg?branch=wb3-7--interacting-with-anomalies-from-smart)](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/signal-k/sytizen/HEAD)
[![](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml/badge.svg?branch=wb3-7--interacting-with-anomalies-from-smart)](https://deepnote.com/workspace/star-sailors-49d2efda-376f-4329-9618-7f871ba16007/project/Supabase-Talk-ab6b31e5-13c3-4949-af38-1197d00bd4d1/notebook/Flask%20API-cb9219547b9e4e228b15cbf8a1aa9cf4#99de0381ef0d40ffaee2354354861bae)
[![](https://badges.thirdweb.com/contract?address=0xCcaA1ABA77Bae6296D386C2F130c46FEc3E5A004&theme=light&chainId=5)](https://thirdweb.com/goerli/0xCcaA1ABA77Bae6296D386C2F130c46FEc3E5A004?utm_source=contract_badge)

# Signal-K/Sytizen Repo
## Related repositories
* [Signal-K/polygon](https://github.com/Signal-K/polygon/issues/26) ↝ Contract interactions
* [Signal-K/client](https://github.com/Signal-K/client) ↝ Frontend for interactions with our contracts

## Documentation
All documentation is visible on [Notion](https://www.notion.so/skinetics/Sample-Planets-Contract-4c3bdcbca4b9450382f9cc4e72e081f7)

# Citizen Science Classifications
## Process
* User mints an anomaly that has appeared in their UI (for now, the webapp, later it will be the game as well)
* API searches for a token that has already been lazy minted with the TIC id of the anomaly (or the identifier of the candidate)
* If there is a token id that has the TIC Id, then claim a copy of that to the `msg.sender` (player’s address) so they can manipulate it in-game
* If the TIC ID has never been minted before, lazy mint a new one with parameters fetched from the data source and send it to `msg.sender`
* Return the IPFS metadata
* Add some buttons that allow manipulations for the NFT (e.g. viewing (reading) metadata (e.g. image/video files, graphs).
* Graphs should be generated in a Jupyter notebook and returned in the Next app.
* User creates post (proposal [Proposal Board → Migration from Vite](https://www.notion.so/Proposal-Board-Migration-from-Vite-2e3ef95e384d4ac1875e0dbbe9a59337)) with the NFT ID for their anomaly and some extra metadata for their discoveries and proposal, and then users can vote
2 changes: 2 additions & 0 deletions Server/.flaskenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FLASK_APP=app.py
FLASK_DEBUG=1
11 changes: 8 additions & 3 deletions Server/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ flask = "*"
flask_cors = "*"
thirdweb-sdk = "*"
python-dotenv = "*"
psycopg2 = "*"
matplotlib = "*"
lightkurve = "*"
nbformat = "*"
gunicorn = "*"
sqlalchemy = "*"
psycopg2-binary = "*"
flask-sqlalchemy = "*"

[dev-packages]

[requires]
python_version = "3.9.9"
Loading

0 comments on commit ef651f5

Please sign in to comment.