added sepolia and scroll
0fce240d
8 file(s) · +248 −71
| 1 | - | # Sample Hardhat Project |
|
| 1 | + | # Cosmic Cowboys Contracts |
|
| 2 | + | ||
| 3 | + | This repo contains the Solidity smart contracts for Cosmic Cowboys, a dynamic on-chain game that gives life to NPC using ERC-6551 and AI. |
|
| 4 | + | ||
| 5 | + | The project consists of several elements: |
|
| 6 | + | - A primary key that can deploy / own the contracts |
|
| 7 | + | - An altered ERC-721 where each NFT is an NPC. The additions to the contract include on-chain state like health and location. |
|
| 8 | + | - ERC-20 Contract for the in game currency |
|
| 9 | + | - Two ERC-1155 Contracts for in game supplies and items |
|
| 10 | + | - A custom "Operator" contract that abstracts the other contracts and allows on chain dynamics. |
|
| 11 | + | - A custom implementation of ERC-6551 for deploying to chains that may not have an implementation address, like Scroll. |
|
| 12 | + | ||
| 13 | + | With this repo we deploy all the previously mentioned contracts and mint 20 NPC characters, give each their own Tokenbound Account, and mint currency and items to those accounts. The end result will also give env variables that can be used for the front end portion of the app. |
|
| 14 | + | ||
| 15 | + | # Deploying |
|
| 16 | + | ||
| 17 | + | Fist clone this repo and install dependences |
|
| 18 | + | ``` |
|
| 19 | + | git clone https://github.com/stevedylandev/cosmic-cowboys-contracts && cd cosmic-cowboys-contracts && npm install |
|
| 20 | + | ``` |
|
| 2 | 21 | ||
| 3 | - | This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract. |
|
| 22 | + | To deploy the contracts you can create a `.env` file with the following variables: |
|
| 4 | 23 | ||
| 5 | - | Try running some of the following tasks: |
|
| 24 | + | ``` |
|
| 25 | + | PRIVATE_KEY= |
|
| 26 | + | ALCHEMY_URL= |
|
| 27 | + | ALCHEMY_URL_BASE= |
|
| 28 | + | ALCHEMY_KEY= |
|
| 29 | + | ALCHEMY_KEY_BASE= |
|
| 30 | + | SEPOLIA_URL= |
|
| 31 | + | SEPOLIA_KEY= |
|
| 32 | + | ETHERSCAN_API_KEY= |
|
| 33 | + | ``` |
|
| 34 | + | Depending what networks you want to deploy to you can alter those variables. |
|
| 6 | 35 | ||
| 7 | - | ```shell |
|
| 8 | - | npx hardhat help |
|
| 9 | - | npx hardhat test |
|
| 10 | - | REPORT_GAS=true npx hardhat test |
|
| 11 | - | npx hardhat node |
|
| 12 | - | npx hardhat run scripts/deploy.js |
|
| 36 | + | Once ready you can deploy with your choice of network like goerli |
|
| 37 | + | ``` |
|
| 38 | + | npx hardhat run scripts/deployContracts.js --network goerli |
|
| 13 | 39 | ``` |
|
| 40 | + | Once you run this it will deploy all contracts as well as setup the NPCs for the game. |
| 58 | 58 | return (health, location); |
|
| 59 | 59 | } |
|
| 60 | 60 | ||
| 61 | - | function goToHome(uint256 tokenId) public { |
|
| 62 | - | //require(cosmicCowboys.ownerOf(tokenId) == tba, "Not owner"); // Check OwnershipTransferred |
|
| 63 | - | cosmicCowboys.goToHome(tokenId); |
|
| 64 | - | uint8 newHealth = cosmicCowboys.getHealth(tokenId) + 2; |
|
| 61 | + | function launchSupplyMission(uint256 tokenId) public { |
|
| 62 | + | uint8 newHealth = cosmicCowboys.getHealth(tokenId) - 2; |
|
| 65 | 63 | cosmicCowboys.setHealth(tokenId, newHealth); |
|
| 66 | 64 | } |
|
| 67 | 65 | ||
| 71 | 69 | ||
| 72 | 70 | function goToSupplyDepot(uint256 tokenId) public { |
|
| 73 | 71 | cosmicCowboys.goToSupplyDepot(tokenId); |
|
| 72 | + | } |
|
| 73 | + | ||
| 74 | + | function goToHome(uint256 tokenId) public { |
|
| 75 | + | //require(cosmicCowboys.ownerOf(tokenId) == tba, "Not owner"); // Check OwnershipTransferred |
|
| 76 | + | cosmicCowboys.goToHome(tokenId); |
|
| 77 | + | uint8 newHealth = cosmicCowboys.getHealth(tokenId) + 2; |
|
| 78 | + | cosmicCowboys.setHealth(tokenId, newHealth); |
|
| 74 | 79 | } |
|
| 75 | 80 | ||
| 76 | 81 | function getOwner() external view returns (address) { |
|
| 13 | 13 | url: "https://sepolia-rpc.scroll.io/" || "", |
|
| 14 | 14 | accounts: |
|
| 15 | 15 | process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], |
|
| 16 | + | gasPrice: 1500000000, |
|
| 17 | + | ||
| 16 | 18 | }, |
|
| 17 | 19 | 'base-goerli': { |
|
| 18 | 20 | url: `${process.env.ALCHEMY_URL_BASE}`, |
| 8 | 8 | "dependencies": { |
|
| 9 | 9 | "@openzeppelin/contracts": "^5.0.0", |
|
| 10 | 10 | "@tokenbound/sdk": "^0.3.12", |
|
| 11 | + | "axios": "^1.5.1", |
|
| 11 | 12 | "dotenv": "^16.3.1", |
|
| 12 | 13 | "ethers": "^6.7.1" |
|
| 13 | 14 | }, |
|
| 2314 | 2315 | "node_modules/asynckit": { |
|
| 2315 | 2316 | "version": "0.4.0", |
|
| 2316 | 2317 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", |
|
| 2317 | - | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", |
|
| 2318 | - | "dev": true, |
|
| 2319 | - | "peer": true |
|
| 2318 | + | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" |
|
| 2320 | 2319 | }, |
|
| 2321 | 2320 | "node_modules/at-least-node": { |
|
| 2322 | 2321 | "version": "1.0.0", |
|
| 2332 | 2331 | "version": "1.5.1", |
|
| 2333 | 2332 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", |
|
| 2334 | 2333 | "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", |
|
| 2335 | - | "dev": true, |
|
| 2336 | - | "peer": true, |
|
| 2337 | 2334 | "dependencies": { |
|
| 2338 | 2335 | "follow-redirects": "^1.15.0", |
|
| 2339 | 2336 | "form-data": "^4.0.0", |
|
| 2817 | 2814 | "version": "1.0.8", |
|
| 2818 | 2815 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", |
|
| 2819 | 2816 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", |
|
| 2820 | - | "dev": true, |
|
| 2821 | - | "peer": true, |
|
| 2822 | 2817 | "dependencies": { |
|
| 2823 | 2818 | "delayed-stream": "~1.0.0" |
|
| 2824 | 2819 | }, |
|
| 3087 | 3082 | "version": "1.0.0", |
|
| 3088 | 3083 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", |
|
| 3089 | 3084 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", |
|
| 3090 | - | "dev": true, |
|
| 3091 | - | "peer": true, |
|
| 3092 | 3085 | "engines": { |
|
| 3093 | 3086 | "node": ">=0.4.0" |
|
| 3094 | 3087 | } |
|
| 3702 | 3695 | "version": "1.15.3", |
|
| 3703 | 3696 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", |
|
| 3704 | 3697 | "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", |
|
| 3705 | - | "dev": true, |
|
| 3706 | 3698 | "funding": [ |
|
| 3707 | 3699 | { |
|
| 3708 | 3700 | "type": "individual", |
|
| 3722 | 3714 | "version": "4.0.0", |
|
| 3723 | 3715 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", |
|
| 3724 | 3716 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", |
|
| 3725 | - | "dev": true, |
|
| 3726 | - | "peer": true, |
|
| 3727 | 3717 | "dependencies": { |
|
| 3728 | 3718 | "asynckit": "^0.4.0", |
|
| 3729 | 3719 | "combined-stream": "^1.0.8", |
|
| 4952 | 4942 | "version": "1.52.0", |
|
| 4953 | 4943 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", |
|
| 4954 | 4944 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", |
|
| 4955 | - | "dev": true, |
|
| 4956 | - | "peer": true, |
|
| 4957 | 4945 | "engines": { |
|
| 4958 | 4946 | "node": ">= 0.6" |
|
| 4959 | 4947 | } |
|
| 4962 | 4950 | "version": "2.1.35", |
|
| 4963 | 4951 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", |
|
| 4964 | 4952 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", |
|
| 4965 | - | "dev": true, |
|
| 4966 | - | "peer": true, |
|
| 4967 | 4953 | "dependencies": { |
|
| 4968 | 4954 | "mime-db": "1.52.0" |
|
| 4969 | 4955 | }, |
|
| 5581 | 5567 | "node_modules/proxy-from-env": { |
|
| 5582 | 5568 | "version": "1.1.0", |
|
| 5583 | 5569 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", |
|
| 5584 | - | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", |
|
| 5585 | - | "dev": true, |
|
| 5586 | - | "peer": true |
|
| 5570 | + | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" |
|
| 5587 | 5571 | }, |
|
| 5588 | 5572 | "node_modules/punycode": { |
|
| 5589 | 5573 | "version": "2.3.0", |
|
| 9 | 9 | "dependencies": { |
|
| 10 | 10 | "@openzeppelin/contracts": "^5.0.0", |
|
| 11 | 11 | "@tokenbound/sdk": "^0.3.12", |
|
| 12 | + | "axios": "^1.5.1", |
|
| 12 | 13 | "dotenv": "^16.3.1", |
|
| 13 | 14 | "ethers": "^6.7.1" |
|
| 14 | 15 | } |
| 1 | + | // Import the ethers library |
|
| 2 | + | const { ethers } = require("hardhat"); |
|
| 3 | + | const axios = require('axios') |
|
| 4 | + | //const provider = new ethers.AlchemyProvider("sepolia", process.env.SEPOLIA_KEY) |
|
| 5 | + | const provider = new ethers.getDefaultProvider("https://rpc.scroll.io") |
|
| 6 | + | const { TokenboundClient } = require("@tokenbound/sdk"); |
|
| 7 | + | ||
| 8 | + | async function Main() { |
|
| 9 | + | const feeData = await provider.getFeeData() |
|
| 10 | + | ||
| 11 | + | // Get the signers from ethers |
|
| 12 | + | const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider) |
|
| 13 | + | console.log(`SERVER_WALLET_PRIVATE_KEY=${process.env.PRIVATE_KEY}`) |
|
| 14 | + | console.log(`SERVER_WALLET_ADDRESS=${wallet.address}`) |
|
| 15 | + | ||
| 16 | + | // Deploy NPC contract |
|
| 17 | + | const NPCContract = await ethers.getContractFactory("CosmicCowboys"); |
|
| 18 | + | const npcContract = await NPCContract.deploy(wallet.address, { gasPrice: feeData.gasPrice }) |
|
| 19 | + | const npcContractAddress = await npcContract.getAddress() |
|
| 20 | + | console.log(`NPC_CONTRACT_ADDRESS=${npcContractAddress}`); |
|
| 21 | + | ||
| 22 | + | // Deploy ERC-20 Contract |
|
| 23 | + | const CurrencyContract = await ethers.getContractFactory("GoldenCorn"); |
|
| 24 | + | const currencyContract = await CurrencyContract.deploy(wallet.address, { gasPrice: feeData.gasPrice }) |
|
| 25 | + | const currencyContractAddress = await currencyContract.getAddress() |
|
| 26 | + | console.log(`CURRENCY_CONTRACT_ADDRESS=${currencyContractAddress}`) |
|
| 27 | + | ||
| 28 | + | // Deploy 1155 Contracts |
|
| 29 | + | const FoodContract = await ethers.getContractFactory("SpaceSlop"); |
|
| 30 | + | const foodContract = await FoodContract.deploy(wallet.address, { gasPrice: feeData.gasPrice }) |
|
| 31 | + | const foodContractAddress = await foodContract.getAddress() |
|
| 32 | + | console.log(`FOOD_CONTRACT_ADDRESS=${foodContractAddress}`); |
|
| 33 | + | ||
| 34 | + | const SupplyContract = await ethers.getContractFactory("JupiterJunk"); |
|
| 35 | + | const supplyContract = await SupplyContract.deploy(wallet.address, { gasPrice: feeData.gasPrice }) |
|
| 36 | + | const supplyContractAddress = await supplyContract.getAddress() |
|
| 37 | + | console.log(`SUPPLY_CONTRACT_ADDRESS=${supplyContractAddress}`); |
|
| 38 | + | ||
| 39 | + | // Deploy ERC6551 |
|
| 40 | + | const RegistryContract = await ethers.getContractFactory("ERC6551Registry"); |
|
| 41 | + | const registryContract = await RegistryContract.deploy({ gasPrice: feeData.gasPrice }) |
|
| 42 | + | const registryContractAddress = await registryContract.getAddress() |
|
| 43 | + | console.log("Registry Contract deployed to address:", registryContractAddress); |
|
| 44 | + | ||
| 45 | + | const AccountContract = await ethers.getContractFactory("ERC6551Account"); |
|
| 46 | + | const accountContract = await AccountContract.deploy({ gasPrice: feeData.gasPrice }) |
|
| 47 | + | const accountContractAddress = await accountContract.getAddress() |
|
| 48 | + | console.log("Account Contract deployed to address:", accountContractAddress); |
|
| 49 | + | ||
| 50 | + | /* const tokenboundClient = new TokenboundClient({ |
|
| 51 | + | walletClient: wallet, |
|
| 52 | + | chainId: 534352, |
|
| 53 | + | implementationAddress: accountContractAddress, |
|
| 54 | + | registryAddress: registryContractAddress, |
|
| 55 | + | }) |
|
| 56 | + | // Deploy Operator Contract |
|
| 57 | + | const OperatorContract = await ethers.getContractFactory("Operator"); |
|
| 58 | + | const operatorContract = await OperatorContract.deploy(wallet.address, npcContractAddress, currencyContractAddress, foodContractAddress, supplyContractAddress) |
|
| 59 | + | const operatorContractAddress = await operatorContract.getAddress() |
|
| 60 | + | console.log(`OPERATOR_CONTRACT_ADDRESS=${operatorContractAddress}`) |
|
| 61 | + | ||
| 62 | + | // Transfer NPC contract to Operator |
|
| 63 | + | await npcContract.transferOwnership(operatorContractAddress); |
|
| 64 | + | await currencyContract.transferOwnership(operatorContractAddress); |
|
| 65 | + | await foodContract.transferOwnership(operatorContractAddress); |
|
| 66 | + | await supplyContract.transferOwnership(operatorContractAddress); |
|
| 67 | + | ||
| 68 | + | for (let i = 0; i < 19; i++) { |
|
| 69 | + | // create NPC |
|
| 70 | + | const npcTx = await operatorContract.createNPC(wallet.address, `ipfs://QmQbwCMwDETHHZ1g8YaSHqLBwCRgVHqFuRNRfiGyNqCcXj/${i}.json`) |
|
| 71 | + | const npcTxReceipt = await npcTx.wait() |
|
| 72 | + | console.log("NPC Created") |
|
| 73 | + | ||
| 74 | + | // After the NPC is created |
|
| 75 | + | const latestTokenId = await operatorContract.getLatestTokenId(); |
|
| 76 | + | ||
| 77 | + | // create TBA for NPC |
|
| 78 | + | const tba = await tokenboundClient.createAccount({ |
|
| 79 | + | tokenContract: npcContractAddress, |
|
| 80 | + | tokenId: latestTokenId, |
|
| 81 | + | }) |
|
| 82 | + | console.log("TBA:", tba) |
|
| 83 | + | ||
| 84 | + | // equip NPC via TBA |
|
| 85 | + | // |
|
| 86 | + | const fundNpcTx = await operatorContract.fundNPC(tba, 20) |
|
| 87 | + | const fundNpxTxReceipt = await fundNpcTx.wait() |
|
| 88 | + | console.log("NPC Funded") |
|
| 89 | + | ||
| 90 | + | const feedNpcTx = await operatorContract.feedNPC(tba, 5) |
|
| 91 | + | const feedNpcTxReceipt = await feedNpcTx.wait() |
|
| 92 | + | console.log("NPC Fed") |
|
| 93 | + | ||
| 94 | + | const supplyNpcTx = await operatorContract.supplyNPC(tba, 5) |
|
| 95 | + | const supplyNpcTxReceipt = await supplyNpcTx.wait() |
|
| 96 | + | console.log("NPC Supplied") |
|
| 97 | + | ||
| 98 | + | } */ |
|
| 99 | + | ||
| 100 | + | ||
| 101 | + | } |
|
| 102 | + | ||
| 103 | + | Main() |
| 1 | + | // Import the ethers library |
|
| 2 | + | const { ethers } = require("hardhat"); |
|
| 3 | + | //const provider = new ethers.AlchemyProvider("sepolia", process.env.SEPOLIA_KEY) |
|
| 4 | + | const provider = new ethers.getDefaultProvider("wss://ethereum-sepolia.publicnode.com") |
|
| 5 | + | const { TokenboundClient } = require("@tokenbound/sdk"); |
|
| 6 | + | ||
| 7 | + | async function Main() { |
|
| 8 | + | ||
| 9 | + | // Get the signers from ethers |
|
| 10 | + | const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider) |
|
| 11 | + | const tokenboundClient = new TokenboundClient({ signer: wallet, chainId: 11155111 }) |
|
| 12 | + | console.log(`SERVER_WALLET_PRIVATE_KEY=${process.env.PRIVATE_KEY}`) |
|
| 13 | + | console.log(`SERVER_WALLET_ADDRESS=${wallet.address}`) |
|
| 14 | + | ||
| 15 | + | // Deploy NPC contract |
|
| 16 | + | const NPCContract = await ethers.getContractFactory("CosmicCowboys"); |
|
| 17 | + | const npcContract = await NPCContract.deploy(wallet.address); |
|
| 18 | + | const npcContractAddress = await npcContract.getAddress() |
|
| 19 | + | console.log(`NPC_CONTRACT_ADDRESS=${npcContractAddress}`); |
|
| 20 | + | ||
| 21 | + | // Deploy ERC-20 Contract |
|
| 22 | + | const CurrencyContract = await ethers.getContractFactory("GoldenCorn"); |
|
| 23 | + | const currencyContract = await CurrencyContract.deploy(wallet.address); |
|
| 24 | + | const currencyContractAddress = await currencyContract.getAddress() |
|
| 25 | + | console.log(`CURRENCY_CONTRACT_ADDRESS=${currencyContractAddress}`) |
|
| 26 | + | ||
| 27 | + | // Deploy 1155 Contracts |
|
| 28 | + | const FoodContract = await ethers.getContractFactory("SpaceSlop"); |
|
| 29 | + | const foodContract = await FoodContract.deploy(wallet.address); |
|
| 30 | + | const foodContractAddress = await foodContract.getAddress() |
|
| 31 | + | console.log(`FOOD_CONTRACT_ADDRESS=${foodContractAddress}`); |
|
| 32 | + | ||
| 33 | + | const SupplyContract = await ethers.getContractFactory("JupiterJunk"); |
|
| 34 | + | const supplyContract = await SupplyContract.deploy(wallet.address); |
|
| 35 | + | const supplyContractAddress = await supplyContract.getAddress() |
|
| 36 | + | console.log(`SUPPLY_CONTRACT_ADDRESS=${supplyContractAddress}`); |
|
| 37 | + | ||
| 38 | + | // Deploy ERC6551 |
|
| 39 | + | /* const RegistryContract = await ethers.getContractFactory("ERC6551Registry"); |
|
| 40 | + | const registryContract = await RegistryContract.deploy(); |
|
| 41 | + | const registryContractAddress = await registryContract.getAddress() |
|
| 42 | + | console.log("Registry Contract deployed to address:", registryContractAddress); |
|
| 43 | + | ||
| 44 | + | const AccountContract = await ethers.getContractFactory("ERC6551Account"); |
|
| 45 | + | const accountContract = await AccountContract.deploy(); |
|
| 46 | + | const accountContractAddress = await accountContract.getAddress() |
|
| 47 | + | console.log("Account Contract deployed to address:", accountContractAddress); */ |
|
| 48 | + | ||
| 49 | + | // Deploy Operator Contract |
|
| 50 | + | const OperatorContract = await ethers.getContractFactory("Operator"); |
|
| 51 | + | const operatorContract = await OperatorContract.deploy(wallet.address, npcContractAddress, currencyContractAddress, foodContractAddress, supplyContractAddress) |
|
| 52 | + | const operatorContractAddress = await operatorContract.getAddress() |
|
| 53 | + | console.log(`OPERATOR_CONTRACT_ADDRESS=${operatorContractAddress}`) |
|
| 54 | + | ||
| 55 | + | // Transfer NPC contract to Operator |
|
| 56 | + | await npcContract.transferOwnership(operatorContractAddress); |
|
| 57 | + | await currencyContract.transferOwnership(operatorContractAddress); |
|
| 58 | + | await foodContract.transferOwnership(operatorContractAddress); |
|
| 59 | + | await supplyContract.transferOwnership(operatorContractAddress); |
|
| 60 | + | ||
| 61 | + | for (let i = 0; i < 19; i++) { |
|
| 62 | + | // create NPC |
|
| 63 | + | const npcTx = await operatorContract.createNPC(wallet.address, `ipfs://QmQbwCMwDETHHZ1g8YaSHqLBwCRgVHqFuRNRfiGyNqCcXj/${i}.json`) |
|
| 64 | + | const npcTxReceipt = await npcTx.wait() |
|
| 65 | + | console.log("NPC Created") |
|
| 66 | + | ||
| 67 | + | // After the NPC is created |
|
| 68 | + | const latestTokenId = await operatorContract.getLatestTokenId(); |
|
| 69 | + | ||
| 70 | + | // create TBA for NPC |
|
| 71 | + | const tba = await tokenboundClient.createAccount({ |
|
| 72 | + | tokenContract: npcContractAddress, |
|
| 73 | + | tokenId: latestTokenId, |
|
| 74 | + | }) |
|
| 75 | + | console.log("TBA:", tba) |
|
| 76 | + | ||
| 77 | + | // equip NPC via TBA |
|
| 78 | + | // |
|
| 79 | + | const fundNpcTx = await operatorContract.fundNPC(tba, 20) |
|
| 80 | + | const fundNpxTxReceipt = await fundNpcTx.wait() |
|
| 81 | + | console.log("NPC Funded") |
|
| 82 | + | ||
| 83 | + | const feedNpcTx = await operatorContract.feedNPC(tba, 5) |
|
| 84 | + | const feedNpcTxReceipt = await feedNpcTx.wait() |
|
| 85 | + | console.log("NPC Fed") |
|
| 86 | + | ||
| 87 | + | const supplyNpcTx = await operatorContract.supplyNPC(tba, 5) |
|
| 88 | + | const supplyNpcTxReceipt = await supplyNpcTx.wait() |
|
| 89 | + | console.log("NPC Supplied") |
|
| 90 | + | ||
| 91 | + | } |
|
| 92 | + | } |
|
| 93 | + | ||
| 94 | + | Main() |
| 1 | - | //const { ethers } = require("hardhat"); |
|
| 2 | - | const ethers = require("ethers") |
|
| 3 | - | const provider = new ethers.AlchemyProvider("goerli", process.env.ALCHEMY_KEY) |
|
| 4 | - | const operatorAbi = require("../artifacts/contracts/Operator.sol/Operator.json") |
|
| 5 | - | const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider) |
|
| 6 | - | const { TokenboundClient } = require("@tokenbound/sdk"); |
|
| 7 | - | ||
| 8 | - | ||
| 9 | - | const main = async () => { |
|
| 10 | - | ||
| 11 | - | const operatorContract = new ethers.Contract(process.env.OPERATOR_CONTRACT_ADDRESS, operatorAbi.abi, wallet) |
|
| 12 | - | const tokenboundClient = new TokenboundClient({ signer: wallet, chainId: 5 }) |
|
| 13 | - | ||
| 14 | - | ||
| 15 | - | for (let i = 0; i < 19; i++) { |
|
| 16 | - | // create NPC |
|
| 17 | - | const npcTx = await operatorContract.createNPC(wallet.address, `ipfs://QmQbwCMwDETHHZ1g8YaSHqLBwCRgVHqFuRNRfiGyNqCcXj/${i}.json`) |
|
| 18 | - | const npcTxReceipt = await npcTx.wait() |
|
| 19 | - | console.log("NPC Created") |
|
| 20 | - | ||
| 21 | - | // After the NPC is created |
|
| 22 | - | const latestTokenId = await operatorContract.getLatestTokenId(); |
|
| 23 | - | ||
| 24 | - | // create TBA for NPC |
|
| 25 | - | const tba = await tokenboundClient.createAccount({ |
|
| 26 | - | tokenContract: process.env.NPC_CONTRACT_ADDRESS, |
|
| 27 | - | tokenId: latestTokenId, |
|
| 28 | - | }) |
|
| 29 | - | console.log("TBA:", tba) |
|
| 30 | - | ||
| 31 | - | // equip NPC via TBA |
|
| 32 | - | ||
| 33 | - | const equipTx = await operatorContract.equipNPC(tba, 20, 5, 5) |
|
| 34 | - | const equipTxReceipt = await equipTx.wait() |
|
| 35 | - | console.log("NPC Equipped") |
|
| 36 | - | } |
|
| 37 | - | } |
|
| 38 | - | ||
| 39 | - | main() |