UNPKG

eths-git

Version:

**eths-git-remote** is a decentralized Git solution designed to manage repositories on-chain. It provides two main components:

130 lines (129 loc) 5.07 kB
import { ethers, Contract } from "ethers"; import { getWallet } from "../../core/wallet/index.js"; import { ETHSFactoryAbi, ETHSRepoAbi, Networks } from "../../core/config/index.js"; /** * ============================ * Common Helpers * ============================ */ function randomRPC(rpcs) { return rpcs[Math.floor(Math.random() * rpcs.length)]; } function getNetworkConfig(chainId) { const config = Networks[chainId]; if (!config) { throw new Error(`Unsupported chain ID: ${chainId}.`); } return config; } async function getSigner(chainId) { const walletData = await getWallet(); const netConfig = getNetworkConfig(chainId); const rpcUrl = randomRPC(netConfig.rpc); const provider = new ethers.JsonRpcProvider(rpcUrl); return new ethers.Wallet(walletData.privateKey, provider); } async function waitForTx(tx, action) { const receipt = await tx.wait(); if (!receipt?.status) { throw new Error(`❌ Transaction failed during: ${action} (tx: ${tx.hash})`); } return receipt; } function validateAddress(address, label = "address") { if (!ethers.isAddress(address)) { throw new Error(`Invalid ${label}: ${address}`); } } async function getRepoContract(repoAddress, chainId) { validateAddress(repoAddress, "repoAddress"); const signer = await getSigner(chainId); return new Contract(repoAddress, ETHSRepoAbi, signer); } /** * ============================ * Factory Contract Methods * ============================ */ export var Factory; (function (Factory) { async function createRepo(repoName, chainId) { const signer = await getSigner(chainId); const { hubAddress } = getNetworkConfig(chainId); const factory = new Contract(hubAddress, ETHSFactoryAbi, signer); const tx = await factory.createRepo(ethers.toUtf8Bytes(repoName)); const receipt = await waitForTx(tx, "createRepo"); const iface = new ethers.Interface(ETHSFactoryAbi); for (const log of receipt.logs) { try { const parsed = iface.parseLog(log); if (parsed?.name === "RepoCreated") { return parsed.args.repo; } } catch { /* skip */ } } throw new Error("Transaction succeeded but no 'RepoCreated' event found"); } Factory.createRepo = createRepo; async function getUserReposPaginated(chainId, start = 0, limit = 50) { const signer = await getSigner(chainId); const { hubAddress } = getNetworkConfig(chainId); const userAddress = await signer.getAddress(); const factory = new Contract(hubAddress, ETHSFactoryAbi, signer); const repos = await factory.getUserReposPaginated(userAddress, start, limit); return repos.map((r) => ({ address: r.repoAddress, name: ethers.toUtf8String(r.repoName), creationTime: new Date(Number(r.creationTime) * 1000), })); } Factory.getUserReposPaginated = getUserReposPaginated; })(Factory || (Factory = {})); /** * ============================ * Repository Contract Methods * ============================ */ export var Repo; (function (Repo) { async function setDefaultBranch(repoAddress, chainId, branchName) { const repo = await getRepoContract(repoAddress, chainId); const tx = await repo.setDefaultBranch(ethers.toUtf8Bytes(branchName)); await waitForTx(tx, "setDefaultBranch"); } Repo.setDefaultBranch = setDefaultBranch; async function addPusher(repoAddress, chainId, account) { validateAddress(account, "account"); const repo = await getRepoContract(repoAddress, chainId); const tx = await repo.addPusher(account); await waitForTx(tx, "addPusher"); } Repo.addPusher = addPusher; async function removePusher(repoAddress, chainId, account) { validateAddress(account, "account"); const repo = await getRepoContract(repoAddress, chainId); const tx = await repo.removePusher(account); await waitForTx(tx, "removePusher"); } Repo.removePusher = removePusher; async function addMaintainer(repoAddress, chainId, account) { validateAddress(account, "account"); const repo = await getRepoContract(repoAddress, chainId); const tx = await repo.addMaintainer(account); await waitForTx(tx, "addMaintainer"); } Repo.addMaintainer = addMaintainer; async function canPush(repoAddress, chainId, account) { validateAddress(account, "account"); const repo = await getRepoContract(repoAddress, chainId); return repo.canPush(account); } Repo.canPush = canPush; async function canForcePush(repoAddress, chainId, refName, account) { validateAddress(account, "account"); const repo = await getRepoContract(repoAddress, chainId); return repo.canForcePush(account, ethers.toUtf8Bytes(refName)); } Repo.canForcePush = canForcePush; })(Repo || (Repo = {}));