feat: apps contract and updated scripts (#268)
* feat: FleekApps contract * feat: update scripts * wip: more helper scripts * chore: remove unused import * test: fix deploy test * chore: fix testing networks * fix: contract helper scripts
This commit is contained in:
parent
74d4a4eb9c
commit
869b9f6e78
|
|
@ -2,6 +2,7 @@
|
|||
cache
|
||||
artifacts
|
||||
deployments/hardhat
|
||||
deployments/local
|
||||
gas-report
|
||||
|
||||
# Foundry
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.7;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
|
||||
import "@openzeppelin/contracts/utils/Base64.sol";
|
||||
import "./util/FleekSVG.sol";
|
||||
import "./FleekERC721.sol";
|
||||
|
||||
contract FleekApps is Initializable, ERC721Upgradeable {
|
||||
using Strings for address;
|
||||
using Base64 for bytes;
|
||||
|
||||
uint256 public bindCount;
|
||||
mapping(uint256 => uint256) public bindings;
|
||||
|
||||
FleekERC721 private main;
|
||||
|
||||
/// @custom:oz-upgrades-unsafe-allow constructor
|
||||
constructor() {
|
||||
_disableInitializers();
|
||||
}
|
||||
|
||||
function initialize(string memory _name, string memory _symbol, address _mainAddress) public initializer {
|
||||
__ERC721_init(_name, _symbol);
|
||||
main = FleekERC721(_mainAddress);
|
||||
}
|
||||
|
||||
modifier _requireMainMinted(uint256 _tokenId) {
|
||||
require(main.ownerOf(_tokenId) != address(0), "Main token does not exist");
|
||||
_;
|
||||
}
|
||||
|
||||
function mint(address _to, uint256 _tokenId) public _requireMainMinted(_tokenId) {
|
||||
_mint(_to, bindCount);
|
||||
bindings[bindCount] = _tokenId;
|
||||
bindCount++;
|
||||
}
|
||||
|
||||
function tokenURI(uint256 _bindId) public view virtual override(ERC721Upgradeable) returns (string memory) {
|
||||
(string memory name, string memory ens, string memory logo, string memory color, string memory ipfsHash) = main
|
||||
.getAppData(bindings[_bindId]);
|
||||
|
||||
// prettier-ignore
|
||||
return string(abi.encodePacked(_baseURI(),
|
||||
abi.encodePacked('{',
|
||||
'"owner":"', ownerOf(_bindId).toHexString(), '",',
|
||||
'"name":"', name, '",',
|
||||
'"image":"', FleekSVG.generateBase64(name, ens, logo, color), '",',
|
||||
'"external_url":"ipfs://', ipfsHash, '"',
|
||||
'}').encode()
|
||||
));
|
||||
}
|
||||
|
||||
function _baseURI() internal view virtual override returns (string memory) {
|
||||
return "data:application/json;base64,";
|
||||
}
|
||||
}
|
||||
|
|
@ -202,6 +202,15 @@ contract FleekERC721 is
|
|||
return (app.name, app.description, app.externalURL, app.ENS, app.currentBuild, app.logo, app.color);
|
||||
}
|
||||
|
||||
function getAppData(
|
||||
uint256 tokenId
|
||||
) public view returns (string memory, string memory, string memory, string memory, string memory) {
|
||||
_requireMinted(tokenId);
|
||||
Token storage app = _apps[tokenId];
|
||||
|
||||
return (app.name, app.ENS, app.logo, app.color.toColorString(), app.builds[app.currentBuild].ipfsHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the last minted tokenId.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import '@openzeppelin/hardhat-upgrades';
|
|||
import * as dotenv from 'dotenv';
|
||||
import { HardhatUserConfig } from 'hardhat/types';
|
||||
import { task, types } from 'hardhat/config';
|
||||
import deploy from './scripts/deploy';
|
||||
import deployFleekERC721 from './scripts/deploy/deploy-fleek-erc721';
|
||||
import deployFleekApps from './scripts/deploy/deploy-fleek-apps';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ const {
|
|||
} = process.env;
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
defaultNetwork: 'hardhat',
|
||||
defaultNetwork: 'local',
|
||||
networks: {
|
||||
hardhat: {
|
||||
chainId: 31337,
|
||||
|
|
@ -57,6 +58,10 @@ const config: HardhatUserConfig = {
|
|||
accounts: PRIVATE_KEY ? [PRIVATE_KEY] : [],
|
||||
chainId: 1,
|
||||
},
|
||||
local: {
|
||||
url: 'http://localhost:8545',
|
||||
accounts: PRIVATE_KEY ? [PRIVATE_KEY] : [],
|
||||
},
|
||||
},
|
||||
gasReporter: {
|
||||
enabled: REPORT_GAS === 'true' || false,
|
||||
|
|
@ -97,9 +102,9 @@ export default config;
|
|||
|
||||
// Use the following command to deploy where the network flag can be replaced with the network you choose:
|
||||
// npx hardhat deploy --network goerli --new-proxy-instance --name "FleekNFAs" --symbol "FLKNFA" --billing "[10000, 20000]"
|
||||
task('deploy', 'Deploy the contracts')
|
||||
task('deploy:FleekERC721', 'Deploy the FleekERC721 contract')
|
||||
.addFlag('newProxyInstance', 'Force to deploy a new proxy instance')
|
||||
.addOptionalParam('name', 'The collection name', 'FleekNFAs', types.string)
|
||||
.addOptionalParam('name', 'The collection name', 'Fleek NFAs', types.string)
|
||||
.addOptionalParam('symbol', 'The collection symbol', 'FLKNFA', types.string)
|
||||
.addOptionalParam(
|
||||
'billing',
|
||||
|
|
@ -107,4 +112,10 @@ task('deploy', 'Deploy the contracts')
|
|||
[],
|
||||
types.json
|
||||
)
|
||||
.setAction(deploy);
|
||||
.setAction(deployFleekERC721);
|
||||
|
||||
task('deploy:FleekApps', 'Deploy the FleekApps contract')
|
||||
.addFlag('newProxyInstance', 'Force to deploy a new proxy instance')
|
||||
.addOptionalParam('name', 'The collection name', 'NFA - Apps', types.string)
|
||||
.addOptionalParam('symbol', 'The collection symbol', 'NFAA', types.string)
|
||||
.setAction(deployFleekApps);
|
||||
|
|
|
|||
|
|
@ -6,13 +6,11 @@
|
|||
"scripts": {
|
||||
"test": "yarn test:hardhat && yarn test:foundry",
|
||||
"test:foundry": "forge test -vvv --fork-url mainnet --fork-block-number 16876149",
|
||||
"test:hardhat": "hardhat test",
|
||||
"test:hardhat": "hardhat test --network hardhat",
|
||||
"format": "prettier --write \"./**/*.{js,json,sol,ts}\"",
|
||||
"node:hardhat": "hardhat node",
|
||||
"deploy:hardhat": "hardhat deploy --network hardhat",
|
||||
"deploy:mumbai": "hardhat deploy --network mumbai",
|
||||
"deploy:sepolia": "hardhat deploy --network sepolia",
|
||||
"deploy:goerli": "hardhat deploy --network goerli",
|
||||
"deploy:FleekERC721": "hardhat deploy:FleekERC721",
|
||||
"deploy:FleekApps": "hardhat deploy:FleekApps",
|
||||
"compile": "hardhat compile",
|
||||
"verify:mumbai": "npx hardhat run ./scripts/verify.js --network mumbai",
|
||||
"verify:goerli": "npx hardhat run ./scripts/verify.js --network goerli",
|
||||
|
|
|
|||
|
|
@ -1,105 +0,0 @@
|
|||
const {
|
||||
deployStore,
|
||||
getCurrentAddressIfSameBytecode,
|
||||
} = require('./utils/deploy-store');
|
||||
const { getProxyAddress, proxyStore } = require('./utils/proxy-store');
|
||||
|
||||
// --- Script Settings ---
|
||||
const CONTRACT_NAME = 'FleekERC721';
|
||||
const DEFAULT_PROXY_SETTINGS = {
|
||||
unsafeAllow: ['external-library-linking'],
|
||||
};
|
||||
const LIBRARIES_TO_DEPLOY = ['FleekSVG'];
|
||||
|
||||
const libraryDeployment = async (hre) => {
|
||||
console.log('Deploying Libraries...');
|
||||
const libraries = {};
|
||||
|
||||
for (const lib of LIBRARIES_TO_DEPLOY) {
|
||||
const libAddress = await getCurrentAddressIfSameBytecode(lib);
|
||||
if (libAddress) {
|
||||
console.log(`Library "${lib}" already deployed at ${libAddress}`);
|
||||
libraries[lib] = libAddress;
|
||||
continue;
|
||||
}
|
||||
const libContract = await hre.ethers.getContractFactory(lib);
|
||||
const libInstance = await libContract.deploy();
|
||||
await libInstance.deployed();
|
||||
await deployStore(hre.network.name, lib, libInstance, false);
|
||||
console.log(`Library "${lib}" deployed at ${libInstance.address}`);
|
||||
libraries[lib] = libInstance.address;
|
||||
}
|
||||
|
||||
return libraries;
|
||||
};
|
||||
|
||||
module.exports = async (taskArgs, hre) => {
|
||||
const { newProxyInstance, name, symbol, billing } = taskArgs;
|
||||
const network = hre.network.name;
|
||||
|
||||
console.log(':: Starting Deployment ::');
|
||||
console.log('Network:', network);
|
||||
console.log('Contract:', CONTRACT_NAME);
|
||||
console.log(':: Arguments ::');
|
||||
console.log(taskArgs);
|
||||
console.log();
|
||||
|
||||
const deployArguments = [name, symbol, billing];
|
||||
|
||||
const libraries = await libraryDeployment(hre);
|
||||
|
||||
const Contract = await ethers.getContractFactory(CONTRACT_NAME, {
|
||||
libraries,
|
||||
});
|
||||
const proxyAddress = await getProxyAddress(CONTRACT_NAME, network);
|
||||
|
||||
let deployResult;
|
||||
|
||||
try {
|
||||
if (!proxyAddress || newProxyInstance)
|
||||
throw new Error('new-proxy-instance');
|
||||
console.log(`Trying to upgrade proxy contract at: "${proxyAddress}"`);
|
||||
deployResult = await upgrades.upgradeProxy(
|
||||
proxyAddress,
|
||||
Contract,
|
||||
DEFAULT_PROXY_SETTINGS
|
||||
);
|
||||
|
||||
console.log('\x1b[32m');
|
||||
console.log(
|
||||
`Contract ${CONTRACT_NAME} upgraded at "${deployResult.address}" by account "${deployResult.signer.address}"`
|
||||
);
|
||||
console.log('\x1b[0m');
|
||||
} catch (e) {
|
||||
if (
|
||||
e.message === 'new-proxy-instance' ||
|
||||
e.message.includes("doesn't look like an ERC 1967 proxy")
|
||||
) {
|
||||
console.log(`Failed to upgrade proxy contract: "${e.message?.trim()}"`);
|
||||
console.log('Creating new proxy contract...');
|
||||
deployResult = await upgrades.deployProxy(
|
||||
Contract,
|
||||
deployArguments,
|
||||
DEFAULT_PROXY_SETTINGS
|
||||
);
|
||||
await deployResult.deployed();
|
||||
await proxyStore(CONTRACT_NAME, deployResult.address, network);
|
||||
|
||||
console.log('\x1b[32m');
|
||||
console.log(
|
||||
`Contract ${CONTRACT_NAME} deployed at "${deployResult.address}" by account "${deployResult.signer.address}"`
|
||||
);
|
||||
console.log('\x1b[0m');
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
await deployStore(network, CONTRACT_NAME, deployResult);
|
||||
} catch (e) {
|
||||
console.error('Could not write deploy files', e);
|
||||
}
|
||||
}
|
||||
|
||||
return deployResult;
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import { HardhatRuntimeEnvironment } from 'hardhat/types';
|
||||
import { deployLibraries } from './deploy-libraries';
|
||||
import { deployContractWithProxy } from './deploy-proxy-contract';
|
||||
import { getContract } from '../util';
|
||||
import { Contract } from 'ethers';
|
||||
|
||||
type TaskArgs = {
|
||||
newProxyInstance: boolean;
|
||||
name: string;
|
||||
symbol: string;
|
||||
};
|
||||
|
||||
export default async (
|
||||
{ newProxyInstance, name, symbol }: TaskArgs,
|
||||
hre: HardhatRuntimeEnvironment
|
||||
): Promise<Contract> => {
|
||||
console.log('Deploying FleekApps...');
|
||||
const libraries = await deployLibraries(['FleekSVG'], hre);
|
||||
|
||||
const mainContract = await getContract('FleekERC721');
|
||||
|
||||
return deployContractWithProxy(
|
||||
{
|
||||
name: 'FleekApps',
|
||||
newProxyInstance,
|
||||
args: [name, symbol, mainContract.address],
|
||||
libraries,
|
||||
},
|
||||
hre
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { HardhatRuntimeEnvironment } from 'hardhat/types';
|
||||
import { deployLibraries } from './deploy-libraries';
|
||||
import { deployContractWithProxy } from './deploy-proxy-contract';
|
||||
import { Contract } from 'ethers';
|
||||
|
||||
type TaskArgs = {
|
||||
newProxyInstance: boolean;
|
||||
name: string;
|
||||
symbol: string;
|
||||
billing: number[];
|
||||
};
|
||||
|
||||
export default async (
|
||||
{ newProxyInstance, name, symbol, billing }: TaskArgs,
|
||||
hre: HardhatRuntimeEnvironment
|
||||
): Promise<Contract> => {
|
||||
console.log('Deploying FleekERC721...');
|
||||
const libraries = await deployLibraries(['FleekSVG'], hre);
|
||||
|
||||
return deployContractWithProxy(
|
||||
{
|
||||
name: 'FleekERC721',
|
||||
newProxyInstance,
|
||||
args: [name, symbol, billing],
|
||||
libraries,
|
||||
},
|
||||
hre
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import {
|
||||
deployStore,
|
||||
getCurrentAddressIfSameBytecode,
|
||||
} from '../utils/deploy-store';
|
||||
import { HardhatRuntimeEnvironment } from 'hardhat/types';
|
||||
|
||||
export const deployLibraries = async (
|
||||
librariesToDeploy: string[],
|
||||
hre: HardhatRuntimeEnvironment
|
||||
) => {
|
||||
console.log('Deploying Libraries...');
|
||||
const libraries: Record<string, string> = {};
|
||||
|
||||
for (const lib of librariesToDeploy) {
|
||||
const libAddress: string = await getCurrentAddressIfSameBytecode(lib);
|
||||
if (libAddress) {
|
||||
console.log(`Library "${lib}" already deployed at ${libAddress}`);
|
||||
libraries[lib] = libAddress;
|
||||
continue;
|
||||
}
|
||||
const libContract = await hre.ethers.getContractFactory(lib);
|
||||
const libInstance = await libContract.deploy();
|
||||
await libInstance.deployed();
|
||||
await deployStore(hre.network.name, lib, libInstance, false);
|
||||
console.log(`Library "${lib}" deployed at ${libInstance.address}`);
|
||||
libraries[lib] = libInstance.address;
|
||||
}
|
||||
|
||||
return libraries;
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import { getProxyAddress, proxyStore } from '../utils/proxy-store';
|
||||
import { deployStore } from '../utils/deploy-store';
|
||||
import { UpgradeProxyOptions } from '@openzeppelin/hardhat-upgrades/dist/utils';
|
||||
import { Contract } from 'ethers';
|
||||
import { HardhatRuntimeEnvironment } from 'hardhat/types';
|
||||
|
||||
const DEFAULT_PROXY_SETTINGS: UpgradeProxyOptions = {
|
||||
unsafeAllow: ['external-library-linking'],
|
||||
};
|
||||
|
||||
type DeployContractArgs = {
|
||||
name: string;
|
||||
newProxyInstance: boolean;
|
||||
args: unknown[];
|
||||
libraries?: Record<string, string>;
|
||||
};
|
||||
|
||||
export const deployContractWithProxy = async (
|
||||
{ name, newProxyInstance, args, libraries }: DeployContractArgs,
|
||||
hre: HardhatRuntimeEnvironment
|
||||
): Promise<Contract> => {
|
||||
// const { newProxyInstance, name, symbol, billing } = taskArgs;
|
||||
const network = hre.network.name;
|
||||
|
||||
console.log(`Deploying: ${name}`);
|
||||
console.log('Arguments:', args);
|
||||
console.log();
|
||||
|
||||
const Contract = await hre.ethers.getContractFactory(name, {
|
||||
libraries,
|
||||
});
|
||||
const proxyAddress = await getProxyAddress(name, network);
|
||||
|
||||
let deployResult;
|
||||
|
||||
try {
|
||||
if (!proxyAddress || newProxyInstance)
|
||||
throw new Error('new-proxy-instance');
|
||||
console.log(`Trying to upgrade proxy contract at: "${proxyAddress}"`);
|
||||
deployResult = await hre.upgrades.upgradeProxy(
|
||||
proxyAddress,
|
||||
Contract,
|
||||
DEFAULT_PROXY_SETTINGS
|
||||
);
|
||||
|
||||
console.log('\x1b[32m');
|
||||
console.log(
|
||||
`Contract ${name} upgraded at "${
|
||||
deployResult.address
|
||||
}" by account "${await deployResult.signer.getAddress()}"`
|
||||
);
|
||||
console.log('\x1b[0m');
|
||||
} catch (e) {
|
||||
if (
|
||||
e instanceof Error &&
|
||||
(e.message === 'new-proxy-instance' ||
|
||||
e.message.includes("doesn't look like an ERC 1967 proxy"))
|
||||
) {
|
||||
console.log(`Failed to upgrade proxy contract: "${e.message?.trim()}"`);
|
||||
console.log('Creating new proxy contract...');
|
||||
deployResult = await hre.upgrades.deployProxy(
|
||||
Contract,
|
||||
args,
|
||||
DEFAULT_PROXY_SETTINGS
|
||||
);
|
||||
await deployResult.deployed();
|
||||
await proxyStore(name, deployResult.address, network);
|
||||
|
||||
console.log('\x1b[32m');
|
||||
console.log(
|
||||
`Contract ${name} deployed at "${
|
||||
deployResult.address
|
||||
}" by account "${await deployResult.signer.getAddress()}"`
|
||||
);
|
||||
console.log('\x1b[0m');
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
await deployStore(network, name, deployResult);
|
||||
} catch (e) {
|
||||
console.error('Could not write deploy files', e);
|
||||
}
|
||||
}
|
||||
|
||||
return deployResult;
|
||||
};
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// npx hardhat run scripts/generate-image.ts --network local
|
||||
|
||||
import { getContract } from './util';
|
||||
|
||||
export const generateImage = async (
|
||||
name: string,
|
||||
ens: string,
|
||||
logo: string,
|
||||
color: string
|
||||
) => {
|
||||
const contract = await getContract('FleekSVG');
|
||||
|
||||
const svg = await contract.generateBase64(name, ens, logo, color);
|
||||
|
||||
console.log('SVG:', svg);
|
||||
};
|
||||
|
||||
generateImage('Fleek', '', '', '#123456');
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// npx hardhat run scripts/get-app.ts --network local
|
||||
|
||||
import { getContract, parseDataURI } from './util';
|
||||
|
||||
const getApp = async (tokenId: number) => {
|
||||
const contract = await getContract('FleekApps');
|
||||
|
||||
const transaction = await contract.tokenURI(tokenId);
|
||||
|
||||
const parsed = parseDataURI(transaction);
|
||||
|
||||
console.log('App:', parsed);
|
||||
};
|
||||
|
||||
getApp(0);
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// npx hardhat run scripts/mint-app.ts --network local
|
||||
|
||||
import { getContract } from './util';
|
||||
|
||||
const mintApp = async (nfaId: number) => {
|
||||
const contract = await getContract('FleekApps');
|
||||
|
||||
const transaction = await contract.mint(
|
||||
'0x7ed735b7095c05d78df169f991f2b7f1a1f1a049',
|
||||
nfaId
|
||||
);
|
||||
|
||||
console.log('Minted app', transaction.hash);
|
||||
};
|
||||
|
||||
mintApp(0);
|
||||
|
|
@ -44,8 +44,9 @@ const DEFAULT_MINTS = {
|
|||
'aave', // name
|
||||
'Earn interest, borrow assets, and build applications', // description
|
||||
'https://aave.com/', // external url
|
||||
'aave.eth', // ens
|
||||
'6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
|
||||
'', // ens
|
||||
'6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash,
|
||||
'bafybeifc5pgon43a2xoeevwq45ftwghzbgtjxc7k4dqlzhqh432wpahigm', // ipfs hash
|
||||
'https://github.com/org/repo', // repo
|
||||
path.resolve(__dirname, '../assets/aave.svg'), // svg
|
||||
],
|
||||
|
|
@ -53,9 +54,10 @@ const DEFAULT_MINTS = {
|
|||
'Uniswap', // name
|
||||
'Swap, earn, and build on the leading decentralized crypto trading protocol', // description
|
||||
'https://uniswap.org/', // external url
|
||||
'uniswap.eth', // ens
|
||||
'', // ens
|
||||
'6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
|
||||
'https://github.com/org/repo', // repo
|
||||
'bafybeidwf6m2lhkdifuxqucgaq547bwyxk2mljwmazvhmyryjr6yjoe3nu', // ipfs hash
|
||||
path.resolve(__dirname, '../assets/uniswap.svg'), // svg
|
||||
],
|
||||
yearn: [
|
||||
|
|
@ -78,7 +80,7 @@ const DEFAULT_MINTS = {
|
|||
],
|
||||
};
|
||||
|
||||
const params = DEFAULT_MINTS.fleek;
|
||||
const params = DEFAULT_MINTS.uniswap;
|
||||
const mintTo = '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049';
|
||||
const verifier = '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049';
|
||||
|
||||
|
|
@ -90,11 +92,15 @@ const verifier = '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049';
|
|||
console.log('SVG Path: ', svgPath);
|
||||
params.push(await getSVGBase64(svgPath));
|
||||
console.log('SVG length: ', params[params.length - 1].length);
|
||||
params.push(await getSVGColor(svgPath));
|
||||
params.push(
|
||||
(await getSVGColor(svgPath))
|
||||
.reduce((a, b, i) => a | (b << ((2 - i) * 8)), 0)
|
||||
.toString()
|
||||
);
|
||||
params.push(false);
|
||||
params.push(verifier);
|
||||
|
||||
const transaction = await contract.mint(...params);
|
||||
|
||||
console.log('Response: ', transaction);
|
||||
console.log('Response: ', transaction.hash);
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
// npx hardhat run scripts/owner-of.ts --network local
|
||||
|
||||
import { getContract } from './util';
|
||||
|
||||
const ownerOf = async (tokenId: number) => {
|
||||
const contract = await getContract('FleekERC721');
|
||||
|
||||
const owner = await contract.ownerOf(tokenId);
|
||||
|
||||
console.log('Owner:', owner);
|
||||
};
|
||||
|
||||
ownerOf(0);
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// npx hardhat run scripts/tokenURI.js --network mumbai/sepolia/goerli
|
||||
const { getContract } = require('./util');
|
||||
const { getContract, parseDataURI } = require('./util');
|
||||
|
||||
// TODO: make this arguments
|
||||
const tokenId = 0;
|
||||
|
|
@ -9,9 +9,7 @@ const tokenId = 0;
|
|||
|
||||
const transaction = await contract.tokenURI(tokenId);
|
||||
|
||||
const parsed = JSON.parse(
|
||||
Buffer.from(transaction.slice(29), 'base64').toString('utf-8')
|
||||
);
|
||||
const parsed = parseDataURI(transaction);
|
||||
|
||||
console.log('Response: ', parsed);
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
module.exports.getContract = async function (contractName) {
|
||||
const proxyDeployments =
|
||||
require(`../deployments/${hre.network.name}/proxy.json`)[contractName];
|
||||
const deployment = require(`../deployments/${hre.network.name}/${contractName}.json`);
|
||||
|
||||
if (!proxyDeployments || !proxyDeployments.length) {
|
||||
if (!deployment) {
|
||||
throw new Error(
|
||||
`No proxy deployments found for "${contractName}" under "${hre.network.name}"`
|
||||
`No deployment found for "${contractName}" under "${hre.network.name}"`
|
||||
);
|
||||
}
|
||||
|
||||
const latestDeployment = proxyDeployments[0];
|
||||
console.log(`Using latest deployment for "${deployment.address}":`);
|
||||
|
||||
return hre.ethers.getContractAt(contractName, latestDeployment.address);
|
||||
return hre.ethers.getContractAt(contractName, deployment.address);
|
||||
};
|
||||
|
||||
module.exports.parseDataURI = function (dataURI) {
|
||||
if (!dataURI.startsWith('data:')) throw new Error('Invalid data URI');
|
||||
const content = dataURI.replace('data:', '');
|
||||
const [type, data] = content.split(';base64,');
|
||||
|
||||
switch (type) {
|
||||
case 'application/json':
|
||||
return JSON.parse(Buffer.from(data, 'base64').toString('utf-8'));
|
||||
default:
|
||||
throw new Error(`Unsupported data URI type: ${type}`);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -81,7 +81,20 @@ const getCurrentAddressIfSameBytecode = async (contractName) => {
|
|||
hre.network.name,
|
||||
contractName
|
||||
));
|
||||
return deployData.bytecode === bytecode ? deployData.address : null;
|
||||
|
||||
if (deployData.bytecode === bytecode) {
|
||||
try {
|
||||
const contract = await hre.ethers.getContractAt(
|
||||
contractName,
|
||||
deployData.address
|
||||
);
|
||||
return contract.address;
|
||||
} catch {
|
||||
console.log(
|
||||
`Contract ${contractName} at ${deployData.address} is not deployed`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ import { expect } from 'chai';
|
|||
import * as hre from 'hardhat';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import deploy from '../../../scripts/deploy';
|
||||
import deploy from '../../../scripts/deploy/deploy-fleek-erc721';
|
||||
import { getImplementationAddress } from '@openzeppelin/upgrades-core';
|
||||
import { Contract } from 'ethers';
|
||||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { Errors, TestConstants } from '../contracts/FleekERC721/helpers';
|
||||
import { TestConstants } from '../contracts/FleekERC721/helpers';
|
||||
|
||||
const taskArgs = {
|
||||
newProxyInstance: false,
|
||||
|
|
@ -28,7 +28,7 @@ const getImplementationContract = async (
|
|||
const deployFixture = async () => {
|
||||
const [owner] = await hre.ethers.getSigners();
|
||||
|
||||
const proxy = (await deploy(taskArgs, hre)) as Contract;
|
||||
const proxy = await deploy(taskArgs, hre);
|
||||
|
||||
const implementation = await getImplementationContract(proxy.address);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue