oga-market / contract /deploy.js
harystyleseze
Oga Market: Day 2 hybrid shopper + creator app for Good Online
dcc955a
// deploy.js β€” compile and deploy ListingNFT.sol to 0G testnet
//
// Usage:
// cd contract
// echo "PRIVATE_KEY=0x..." > .env
// npm install
// node deploy.js
//
// Prints the deployed address β€” paste into ../shared.js OG_CHAIN.listingNFT
import { readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
import { ethers } from 'ethers';
import solc from 'solc';
import 'dotenv/config';
const __dirname = dirname(fileURLToPath(import.meta.url));
const OG_RPC = 'https://evmrpc-testnet.0g.ai';
const OG_CHAIN_ID = 16602;
function compile() {
console.log('Compiling ListingNFT.sol…');
const source = readFileSync(resolve(__dirname, 'ListingNFT.sol'), 'utf8');
const input = {
language: 'Solidity',
sources: { 'ListingNFT.sol': { content: source } },
settings: {
outputSelection: { '*': { '*': ['abi', 'evm.bytecode.object'] } },
optimizer: { enabled: true, runs: 200 },
},
};
const output = JSON.parse(solc.compile(JSON.stringify(input)));
if (output.errors) {
for (const err of output.errors) {
if (err.severity === 'error') {
console.error(err.formattedMessage);
process.exit(1);
}
}
}
const contract = output.contracts['ListingNFT.sol']['ListingNFT'];
const abi = contract.abi;
const bytecode = contract.evm.bytecode.object;
// Save artifacts for the frontend
writeFileSync(resolve(__dirname, 'ListingNFT.abi.json'), JSON.stringify(abi, null, 2));
writeFileSync(resolve(__dirname, 'ListingNFT.bytecode'), bytecode);
console.log('Compiled. ABI + bytecode written to contract/.');
return { abi, bytecode };
}
async function deploy() {
const privateKey = process.env.PRIVATE_KEY;
if (!privateKey) {
console.error('Missing PRIVATE_KEY in contract/.env');
console.error('Create one: echo "PRIVATE_KEY=0x..." > .env');
process.exit(1);
}
const { abi, bytecode } = compile();
console.log('Connecting to 0G testnet…');
const provider = new ethers.JsonRpcProvider(OG_RPC);
const wallet = new ethers.Wallet(privateKey, provider);
const network = await provider.getNetwork();
if (Number(network.chainId) !== OG_CHAIN_ID) {
console.warn(`Warning: chainId is ${network.chainId}, expected ${OG_CHAIN_ID}`);
}
const balance = await provider.getBalance(wallet.address);
console.log(`Wallet: ${wallet.address}`);
console.log(`Balance: ${ethers.formatEther(balance)} 0G`);
if (balance === 0n) {
console.error('Wallet has 0 balance. Get testnet tokens at https://faucet.0g.ai');
process.exit(1);
}
console.log('Deploying ListingNFT…');
const factory = new ethers.ContractFactory(abi, '0x' + bytecode, wallet);
const contract = await factory.deploy();
console.log(`Tx submitted: ${contract.deploymentTransaction().hash}`);
console.log('Waiting for confirmation…');
await contract.waitForDeployment();
const addr = await contract.getAddress();
console.log('');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('βœ“ Deployed!');
console.log('');
console.log(`Address: ${addr}`);
console.log(`Explorer: https://chainscan-galileo.0g.ai/address/${addr}`);
console.log('');
console.log('Next step:');
console.log(' Edit ../shared.js and set:');
console.log(` OG_CHAIN.listingNFT = '${addr}'`);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
}
deploy().catch(e => {
console.error('Deploy failed:', e);
process.exit(1);
});