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

Hyperverse Polygon RandomPick #49

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
10 changes: 10 additions & 0 deletions packages/hyperverse-polygon-randompick/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
.env
coverage
coverage.json
typechain

#Hardhat files
cache
artifacts
distribution
5 changes: 5 additions & 0 deletions packages/hyperverse-polygon-randompick/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# @decentology/hyperverse-polygon-randompick

## 1.0.0

- initializing package
70 changes: 70 additions & 0 deletions packages/hyperverse-polygon-randompick/contracts/RandomPick.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";

/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
contract RandomPick is VRFConsumerBase {
bytes32 internal keyHash;
uint256 internal fee;
// Where you can access your results
// requestId => result
mapping(bytes32 => int256) public results;
/* Helpers along the way */
// requestId => input
mapping(bytes32 => int256[]) public randomList;
// requestId => tenant address
mapping(bytes32 => address) public requestIdToAddress;
event StartedRandomPick(address tenant, bytes32 requestId);

/**
* Constructor inherits VRFConsumerBase
* All of this info is gotten from: https://docs.chain.link/docs/vrf-contracts/
*
* Network: Rinkeby
* Chainlink VRF Coordinator address: 0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B
* LINK token address: 0x01BE23585060835E02B77ef475b0Cc51aA1e0709
* Key Hash: 0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311
* Fee: 0.1 LINK
*/
constructor()
VRFConsumerBase(
0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B, // VRF Coordinator
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe these are the contracts for Ethereum. There is some documentation around this here

https://blog.chain.link/how-to-get-a-random-number-on-polygon/

Potential contracts

constructor() 
        VRFConsumerBase(
            0x8C7382F9D8f56b33781fE506E897a4F1e2d17255
            0x326C977E6efc84E512bB9C30f76E30c160eD06FB
        ) public
    {
        keyHash = 0x6e75b569a01ef56d18cab6a8e71e6600d6ce853834d4a5748b720d06f878b3a4;
        fee = 100000000000000; // 0.0001 LINK
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jsheely cool I'll make the adjustments and push when I've got time. I'm still learning how this all fits together.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jsheely i think this is the blocker for the moment on this PR. I'll update my branch for testnet and then maybe we can create another issue for discussion on how to move forward on mainnet?
Screen Shot 2022-03-21 at 7 58 20 PM

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jsheely do I need to generate the ABI to go along with updating the contract?

0x01BE23585060835E02B77ef475b0Cc51aA1e0709 // LINK Token on Rinkeby
)
{
keyHash = 0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311;
fee = 0.1 * 10**18; // 0.1 LINK (Varies by network)
}

/**
* Requests randomness
* Everything set in here is done on the first transaction
*/
function startRandomPick(int256[] memory numbers) public returns (bytes32) {
require(
LINK.balanceOf(address(this)) >= fee,
"Not enough LINK - fill contract with faucet"
);
bytes32 requestId = requestRandomness(keyHash, fee);
randomList[requestId] = numbers;
requestIdToAddress[requestId] = msg.sender;
emit StartedRandomPick(msg.sender, requestId);
return requestId;
}

/**
* Callback function used by VRF Coordinator
* Everything set in here is done on the second transaction
*/
function fulfillRandomness(bytes32 requestId, uint256 randomness)
internal
override
{
uint256 length = randomList[requestId].length;
uint256 index = randomness % length;
results[requestId] = randomList[requestId][index];
}
}
21 changes: 21 additions & 0 deletions packages/hyperverse-polygon-randompick/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require("@nomiclabs/hardhat-waffle");

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();

for (const account of accounts) {
console.log(account.address);
}
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
};
1 change: 1 addition & 0 deletions packages/hyperverse-polygon-randompick/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./source";
44 changes: 44 additions & 0 deletions packages/hyperverse-polygon-randompick/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@decentology/hyperverse-polygon-randompick",
"version": "1.0.0",
"source": "./source/index.ts",
"types": "./distribution/index.d.ts",
"main": "./distribution/index.js",
"license": "MIT",
"scripts": {
"test": "hardhat test",
"build": "parcel build",
"clean": "rimraf ./distribution"
},
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"react": "^17.0.2"
},
"files": [
"distribution",
"utils"
],
"dependencies": {
"@chainlink/contracts": "^0.4.0",
"@decentology/hyperverse": "^1.0.9",
"@decentology/hyperverse-polygon": "^1.0.0",
"@decentology/hyperverse-storage-skynet": "^1.0.8",
"@decentology/unstated-next": "^1.1.1",
"ethers": "^5.5.3",
"react-query": "^3.34.7",
"react-use": "^17.3.2",
"skynet-js": "^4.0.23-beta"
},
"devDependencies": {
"@decentology/config": "^1.0.0",
"@nomiclabs/hardhat-ethers": "^2.0.4",
"@nomiclabs/hardhat-waffle": "^2.0.2",
"chai": "^4.3.4",
"ethereum-waffle": "^3.4.0",
"hardhat": "^2.8.3",
"parcel": "^2.2.1",
"rimraf": "^3.0.2"
}
}
22 changes: 22 additions & 0 deletions packages/hyperverse-polygon-randompick/source/Provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FC } from "react";
import { QueryClientProvider, QueryClient } from "react-query";
import ABI from "../utils/RandomPick.json";
import { HyperverseModuleInstance } from "@decentology/hyperverse";
import { RandomPick } from "./useRandomPick";
const client = new QueryClient();

export const ContractABI = ABI.abi;
export const CONTRACT_ADDRESS = "0x9FC0FE344758ff0dB70Aa7c864b2de53A79CA776";
export const TENANT_ADDRESS = "0x45e4c90801b1a17c178bB9855aA181A886DAA603";

const Provider: FC<HyperverseModuleInstance> = ({ children, tenantId }:{children: any, tenantId: string}) => {
return (
<QueryClientProvider client={client}>
<RandomPick.Provider initialState={{ tenantId: tenantId || TENANT_ADDRESS }}>
{children}
</RandomPick.Provider>
</QueryClientProvider>
);
};

export { Provider };
2 changes: 2 additions & 0 deletions packages/hyperverse-polygon-randompick/source/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { useRandomPick } from './useRandomPick'
export { Provider } from "./Provider";
104 changes: 104 additions & 0 deletions packages/hyperverse-polygon-randompick/source/useRandomPick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { useState, useEffect, useCallback } from "react";
import { useMutation, UseMutationOptions, useQuery } from "react-query";
import { BigNumber, ethers } from "ethers";
import { usePolygon } from "@decentology/hyperverse-polygon";
import { ContractABI, CONTRACT_ADDRESS } from "./Provider";
import { createContainer, useContainer } from "@decentology/unstated-next";

type ContractState = ethers.Contract;
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
function RandomPickState(
initialState: { tenantId: string } = { tenantId: "" }
) {
const { tenantId } = initialState;
const { address, web3Provider, provider, connect } = usePolygon();
const [contract, setRandomPickContract] = useState<ContractState>(
new ethers.Contract(
CONTRACT_ADDRESS,
ContractABI,
provider
) as ContractState
);

const setup = useCallback(async () => {
const signer = await web3Provider?.getSigner();
if (signer && contract) {
const ctr = contract.connect(signer) as ContractState;
setRandomPickContract(ctr);
}
}, [web3Provider]);

const errors = (err: any) => {
throw err;
// throw new Error("Something went wrong!");
};

useEffect(() => {
if (web3Provider) {
setup();
}
}, [web3Provider]);

const startRandomPick = useCallback(
async (numbers: Number[]) => {
try {
const tx = await contract.startRandomPick(numbers);
console.log("Sending...");
const waited = await tx.wait();
const event = waited.events.filter(
(x: any) => x.event == "StartedRandomPick"
)[0];
const requestId = event.args[1];
console.log("RequestId:", requestId);
return requestId;
} catch (err) {
errors(err);
throw err;
}
},
[contract]
);

const getRandomPick = useCallback(
async (requestId: string) => {
return new Promise<number>(async (resolve, reject) => {
try {
if (!requestId) {
return null;
}
let randomPick = (await contract.results(requestId)) as BigNumber;
while (randomPick.toNumber() === 0) {
await sleep(1000);
randomPick = (await contract.results(requestId)) as BigNumber;
}

return resolve(randomPick.toNumber());
} catch (err) {
return reject(err);
}
});
},
[contract]
);

return {
tenantId,
contract,
StartRandomPick: (
options?: Omit<
UseMutationOptions<unknown, unknown, void, unknown>,
"mutationFn"
>
) => useMutation((numbers: Number[]) => startRandomPick(numbers)),
GetRandomPick: (requestId: string) =>
useQuery(["getRandomPick"], () => getRandomPick(requestId), {
enabled: !!requestId,
}),
};
}

export const RandomPick = createContainer(RandomPickState);

export function useRandomPick() {
return useContainer(RandomPick);
}
Empty file.
8 changes: 8 additions & 0 deletions packages/hyperverse-polygon-randompick/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "@decentology/config/react-library.json",
"include": ["source/**/*.ts", "source/**/*.tsx", "**/*.json"],
"exclude": ["distribution", "node_modules"],
"compilerOptions": {
"resolveJsonModule": true
}
}
Loading