Skip to content

Commit

Permalink
Merge pull request #20 from BibliothecaDAO/veLords-deploy
Browse files Browse the repository at this point in the history
veLords deploy config
  • Loading branch information
credence0x authored Aug 26, 2024
2 parents 08a415e + 73bf8c3 commit 50ed2b4
Show file tree
Hide file tree
Showing 11 changed files with 865 additions and 9 deletions.
8 changes: 8 additions & 0 deletions veLords/scripts/deployment/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export RPC_API_KEY=https://starknet-sepolia.public.blastapi.io
export STARKNET_NETWORK=sepolia
export STARKNET_ACCOUNT_ADDRESS=
export STARKNET_ACCOUNT_PRIVATE_KEY=

export LORDS_TOKEN=0x0
export VELORDS_ADMIN=0x0
export REWARD_POOL_ADMIN=0x0
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"address": "0x5d748db07d5d307a9ba2ada904209278eb50816cf238f8195dfbc266113a703",
"calldata": [
"0x272fb197b288ab6a441b80a60f60eef66ff7d5e9d8adc4f1d45fb3d9a0c4205",
"0x38306182f5f04496efc0db2e533874d41c9ae298af9a42405218bf58f8e57d2",
"0x19c92fa87f4d5e3be25c3dd6a284f30282a07e87cd782f5fd387b82c8142017",
1724350629
],
"deployed_at": 1724350653125,
"deployed_at_readable": "Thu, 22 Aug 2024 18:17:33 GMT"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"address": "0x38306182f5f04496efc0db2e533874d41c9ae298af9a42405218bf58f8e57d2",
"calldata": [
"0x19c92fa87f4d5e3be25c3dd6a284f30282a07e87cd782f5fd387b82c8142017",
"0x272fb197b288ab6a441b80a60f60eef66ff7d5e9d8adc4f1d45fb3d9a0c4205"
],
"deployed_at": 1724350608178,
"deployed_at_readable": "Thu, 22 Aug 2024 18:16:48 GMT"
}
6 changes: 6 additions & 0 deletions veLords/scripts/deployment/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

cd ../../ && \
scarb --release build && \
cd - && \
node startDeploy
163 changes: 163 additions & 0 deletions veLords/scripts/deployment/libs/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import "dotenv/config";
import * as fs from "fs";
import * as path from "path";
import { json } from "starknet";
import { getNetwork, getAccount } from "./network.js";
import colors from "colors";
import { promisify } from "util";


export const getContracts = (TARGET_PATH) => {
if (!fs.existsSync(TARGET_PATH)) {
throw new Error(`Target directory not found at path: ${TARGET_PATH}`);
}
const contracts = fs
.readdirSync(TARGET_PATH)
.filter((contract) => contract.includes(".contract_class.json"));
if (contracts.length === 0) {
throw new Error("No build files found. Run `scarb build` first");
}
return contracts;
};

export const getContractPath = (TARGET_PATH, contract_name) => {
const contracts = getContracts(TARGET_PATH);
const c = contracts.find((contract) => contract.includes(contract_name));
if (!c) {
throw new Error(`Contract not found: ${contract_name}`);
}
console.log(`\n\n\nContract is ${c}...\n\n`.blue);
return path.join(TARGET_PATH, c);
};


export const declare = async (filepath, contract_name) => {
console.log(`\nDeclaring ${contract_name}...\n\n`.magenta);
const compiledSierraCasm = filepath.replace(
".contract_class.json",
".compiled_contract_class.json"
);
const compiledFile = json.parse(fs.readFileSync(filepath).toString("ascii"));
const compiledSierraCasmFile = json.parse(
fs.readFileSync(compiledSierraCasm).toString("ascii")
);

const account = getAccount();
const contract = await account.declareIfNot({
contract: compiledFile,
casm: compiledSierraCasmFile,
});


const network = getNetwork(process.env.STARKNET_NETWORK);
console.log(`- Class Hash: `.magenta, `${contract.class_hash}`);
if (contract.transaction_hash) {
console.log(
"- Tx Hash: ".magenta,
`${network.explorer_url}/tx/${contract.transaction_hash})`
);
await account.waitForTransaction(contract.transaction_hash);
} else {
console.log("- Tx Hash: ".magenta, "Already declared");
}

return contract;
};


export const deploy = async (name, class_hash, constructorCalldata) => {
// Deploy contract
const account = getAccount();
console.log(`\nDeploying ${name} ... \n\n`.green);
let contract = await account.deployContract({
classHash: class_hash,
constructorCalldata: constructorCalldata,
});

// Wait for transaction
let network = getNetwork(process.env.STARKNET_NETWORK);
console.log(
"Tx hash: ".green,
`${network.explorer_url}/tx/${contract.transaction_hash})`
);
let a = await account.waitForTransaction(contract.transaction_hash);
console.log("Contract Address: ".green, contract.address, "\n\n");

await writeDeploymentToFile(
name,
contract.address,
constructorCalldata
);

return contract.address
};



const mkdirAsync = promisify(fs.mkdir);
const writeFileAsync = promisify(fs.writeFile);
export const writeDeploymentToFile = async (
contractName,
address,
calldata
) => {
try {
const folderPath = process.env.DEPLOYMENT_ADDRESSES_FOLDER;
await mkdirAsync(folderPath, { recursive: true });

const fileName = path.join(folderPath, `${contractName}.json`);

const data = {
address,
calldata,
deployed_at: Date.now(),
deployed_at_readable: new Date().toUTCString(),
};

// Convert BigInt to hex string
const jsonString = JSON.stringify(
data,
(key, value) => {
if (typeof value === "bigint") {
return "0x" + value.toString(16);
}
return value;
},
2
);

await writeFileAsync(fileName, jsonString);
console.log(`"${fileName}" has been saved or overwritten`);
} catch (err) {
console.error("Error writing file", err);
throw err; // Re-throw the error so the caller knows something went wrong
}
};




const readFileAsync = promisify(fs.readFile);

export const getDeployedAddress = async (contractName) => {
const folderPath = process.env.DEPLOYMENT_ADDRESSES_FOLDER;
const fileName = path.join(folderPath, `${contractName}.json`);

try {

const data = await readFileAsync(fileName, "utf8");
const jsonData = JSON.parse(data);

return jsonData.address;
} catch (err) {
if (err.code === "ENOENT") {
console.error(`File not found: ${fileName}`);
} else if (err instanceof SyntaxError) {
console.error("Error parsing JSON:", err);
} else {
console.error("Error reading file:", err);
}
throw err; // Re-throw the error so the caller knows something went wrong
}
};

107 changes: 107 additions & 0 deletions veLords/scripts/deployment/libs/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import "dotenv/config";
import * as path from "path";
import { fileURLToPath } from "url";
import { declare, getContractPath, deploy } from "./common.js";
import { getAccount, getNetwork } from "./network.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const TARGET_PATH = path.join(__dirname, "..", "..", "..", "target", "release");



export const deployVeLords = async () => {
///////////////////////////////////////////
//////// VeLords /////////////
///////////////////////////////////////////

// declare contract
let realName = "Lordship veLords";
let contractName = "lordship_velords";
const class_hash = (
await declare(getContractPath(TARGET_PATH, contractName), realName)
).class_hash;

// deploy contract
let LORDS_TOKEN = BigInt(process.env.LORDS_TOKEN);
let VELORDS_ADMIN = BigInt(process.env.VELORDS_ADMIN);
let constructorCalldata = [LORDS_TOKEN, VELORDS_ADMIN];
let address = await deploy(realName, class_hash, constructorCalldata);
return address;
};


export const deployDLords = async () => {
///////////////////////////////////////////
//////// DLords /////////////
///////////////////////////////////////////

// declare contract
let realName = "Lordship dLords";
let contractName = "lordship_dlords";
const class_hash = (
await declare(getContractPath(TARGET_PATH, contractName), realName)
).class_hash;

// deploy contract
let DLORDS_ADMIN = BigInt(process.env.DLORDS_ADMIN);
let constructorCalldata = [DLORDS_ADMIN];
let address = await deploy(realName, class_hash, constructorCalldata);
return address;
};


export const deployRewardPool = async (veLordsAddress) => {
///////////////////////////////////////////
//////// Reward Pool /////////////
///////////////////////////////////////////

// declare contract
let realName = "Lordship veLords Reward Pool";
let contractName = "lordship_reward_pool";
const class_hash = (
await declare(getContractPath(TARGET_PATH, contractName), realName)
).class_hash;

// deploy contract
let RP_ADMIN = BigInt(process.env.REWARD_POOL_ADMIN);
let RP_VELORDS_ADDRESS = veLordsAddress;
let RP_REWARD_TOKEN_ADDRESS = BigInt(process.env.LORDS_TOKEN);
let RP_TIMESTAMP_NOW = Math.round(Date.now() / 1000);
let constructorCalldata = [
RP_ADMIN,
RP_VELORDS_ADDRESS,
RP_REWARD_TOKEN_ADDRESS,
RP_TIMESTAMP_NOW
];
let address = await deploy(realName, class_hash, constructorCalldata);
return address
};


export const setRewardPoolInVeLords = async (veLords, rewardPool) => {
///////////////////////////////////////////
///// Set Reward Pool in veLords ////
///////////////////////////////////////////

const account = getAccount();
console.log(`\n Setting Reward Pool ... \n\n`.green);

const contract = await account.execute([
{
contractAddress: veLords,
entrypoint: "set_reward_pool",
calldata: [rewardPool],
}
]);

// Wait for transaction
let network = getNetwork(process.env.STARKNET_NETWORK);
console.log(
"Tx hash: ".green,
`${network.explorer_url}/tx/${contract.transaction_hash})`
);
await account.waitForTransaction(contract.transaction_hash);

console.log("Successfully set reward pool in veLords".green, "\n\n");
};
39 changes: 39 additions & 0 deletions veLords/scripts/deployment/libs/network.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import "dotenv/config";
import { Account, RpcProvider, json } from "starknet";

const NETWORKS = {
mainnet: {
name: "mainnet",
explorer_url: "https://voyager.online",
rpc_url: `${process.env.RPC_API_KEY}`,
feeder_gateway_url: "https://alpha-mainnet.starknet.io/feeder_gateway",
gateway_url: "https://alpha-mainnet.starknet.io/gateway",
},
sepolia: {
name: "sepolia",
explorer_url: "https://sepolia.voyager.online",
rpc_url: `https://free-rpc.nethermind.io/sepolia-juno`,
feeder_gateway_url: "https://alpha-sepolia.starknet.io/feeder_gateway",
gateway_url: "https://alpha-sepolia.starknet.io/gateway",
},
};

export const getNetwork = (network) => {
if (!NETWORKS[network.toLowerCase()]) {
throw new Error(`Network ${network} not found`);
}
return NETWORKS[network.toLowerCase()];
};

export const getProvider = () => {
let network = getNetwork(process.env.STARKNET_NETWORK);
return new RpcProvider({ nodeUrl: network.rpc_url });
};

export const getAccount = () => {
const provider = getProvider();
const accountAddress = process.env.STARKNET_ACCOUNT_ADDRESS;
const privateKey = process.env.STARKNET_ACCOUNT_PRIVATE_KEY;
const cairoVersion = "1";
return new Account(provider, accountAddress, privateKey, cairoVersion);
};
Loading

0 comments on commit 50ed2b4

Please sign in to comment.