|
|
@ -5,9 +5,12 @@ import bip39 from "bip39"
|
|
|
|
import inquirer from "inquirer"
|
|
|
|
import inquirer from "inquirer"
|
|
|
|
import { importActions, generateActions } from "./actions.js"
|
|
|
|
import { importActions, generateActions } from "./actions.js"
|
|
|
|
import network from "../config/evm-network.js"
|
|
|
|
import network from "../config/evm-network.js"
|
|
|
|
import { getWallet, randomRPC } from "../common/wallet.js"
|
|
|
|
import { explorerTxUrl, getWallet, randomRPC, setupContract } from "../common/wallet.js"
|
|
|
|
import { parseGit3URI } from "../common/git3-protocol.js"
|
|
|
|
import { parseGit3URI } from "../common/git3-protocol.js"
|
|
|
|
import { TxManager } from "../common/tx-manager.js"
|
|
|
|
import { TxManager } from "../common/tx-manager.js"
|
|
|
|
|
|
|
|
import nameServices from "../config/name-services.js"
|
|
|
|
|
|
|
|
import abis from "../config/abis.js"
|
|
|
|
|
|
|
|
|
|
|
|
const program = new Command()
|
|
|
|
const program = new Command()
|
|
|
|
|
|
|
|
|
|
|
|
program.name("git3").description("git3 mangement tool").version("0.1.0")
|
|
|
|
program.name("git3").description("git3 mangement tool").version("0.1.0")
|
|
|
@ -20,8 +23,7 @@ program
|
|
|
|
.action(() => {
|
|
|
|
.action(() => {
|
|
|
|
inquirer.prompt(generateActions).then((answers) => {
|
|
|
|
inquirer.prompt(generateActions).then((answers) => {
|
|
|
|
const { keyType, name } = answers
|
|
|
|
const { keyType, name } = answers
|
|
|
|
const walletType =
|
|
|
|
const walletType = keyType === "private key" ? "privateKey" : "mnemonic"
|
|
|
|
keyType === "private key" ? "privateKey" : "mnemonic"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const keyPath = process.env.HOME + "/.git3/keys"
|
|
|
|
const keyPath = process.env.HOME + "/.git3/keys"
|
|
|
|
mkdirSync(keyPath, { recursive: true })
|
|
|
|
mkdirSync(keyPath, { recursive: true })
|
|
|
@ -64,9 +66,7 @@ program
|
|
|
|
|
|
|
|
|
|
|
|
if (params.raw) {
|
|
|
|
if (params.raw) {
|
|
|
|
console.log(`[${file}]`)
|
|
|
|
console.log(`[${file}]`)
|
|
|
|
console.log(
|
|
|
|
console.log(` ${content.split("\n")[0]} - ${content.split("\n")[1]}`)
|
|
|
|
` ${content.split("\n")[0]} - ${content.split("\n")[1]}`
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
console.log("\t")
|
|
|
|
console.log("\t")
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -89,8 +89,7 @@ program
|
|
|
|
.action(() => {
|
|
|
|
.action(() => {
|
|
|
|
inquirer.prompt(importActions).then((answers) => {
|
|
|
|
inquirer.prompt(importActions).then((answers) => {
|
|
|
|
const { keyType, key, name } = answers
|
|
|
|
const { keyType, key, name } = answers
|
|
|
|
const walletType =
|
|
|
|
const walletType = keyType === "private key" ? "privateKey" : "mnemonic"
|
|
|
|
keyType === "private key" ? "privateKey" : "mnemonic"
|
|
|
|
|
|
|
|
const keyPath = process.env.HOME + "/.git3/keys"
|
|
|
|
const keyPath = process.env.HOME + "/.git3/keys"
|
|
|
|
mkdirSync(keyPath, { recursive: true })
|
|
|
|
mkdirSync(keyPath, { recursive: true })
|
|
|
|
|
|
|
|
|
|
|
@ -114,9 +113,7 @@ program
|
|
|
|
const wallets = readdirSync(keyPath)
|
|
|
|
const wallets = readdirSync(keyPath)
|
|
|
|
|
|
|
|
|
|
|
|
if (wallets.length === 0) {
|
|
|
|
if (wallets.length === 0) {
|
|
|
|
console.error(
|
|
|
|
console.error("No wallet found, you can generate one with `git3 generate`")
|
|
|
|
"No wallet found, you can generate one with `git3 generate`"
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -135,49 +132,108 @@ program
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
program
|
|
|
|
let create = program
|
|
|
|
.command("create")
|
|
|
|
.command("create")
|
|
|
|
|
|
|
|
.description("create hub [is_permissionless] OR create repo <uri>")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
create
|
|
|
|
|
|
|
|
.command("hub")
|
|
|
|
|
|
|
|
.argument("<chain>", "chain name or chain id")
|
|
|
|
|
|
|
|
.argument("[is_permissionless]", "true or false", false)
|
|
|
|
|
|
|
|
.description("create a new hub")
|
|
|
|
|
|
|
|
.action(async (chain, isPermissionless) => {
|
|
|
|
|
|
|
|
let netConfig, chainId
|
|
|
|
|
|
|
|
chainId = parseInt(chain)
|
|
|
|
|
|
|
|
if (chainId) {
|
|
|
|
|
|
|
|
netConfig = network[chainId]
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
let ns = nameServices[chain]
|
|
|
|
|
|
|
|
if (!ns) throw new Error(`invalid name service ${chain}`)
|
|
|
|
|
|
|
|
chainId = ns.chainId
|
|
|
|
|
|
|
|
netConfig = network[chainId]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const wallet = await getWallet()
|
|
|
|
|
|
|
|
let rpc = randomRPC(netConfig.rpc)
|
|
|
|
|
|
|
|
const provider = new ethers.providers.JsonRpcProvider(rpc)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let factory = setupContract(provider, netConfig.contracts.factory, abis.Factory, wallet)
|
|
|
|
|
|
|
|
let txManager = new TxManager(factory, chainId, netConfig.txConst)
|
|
|
|
|
|
|
|
let receipt = await txManager.SendCall("createHub", [isPermissionless])
|
|
|
|
|
|
|
|
// let CreateHubEvent = factory.interface.getEvent("CreateHub");
|
|
|
|
|
|
|
|
console.log(explorerTxUrl(receipt.transactionHash, netConfig.explorers))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let events = receipt.logs
|
|
|
|
|
|
|
|
.map((log: any) => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
return factory.interface.parseLog(log)
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
return null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.filter((item: any) => item !== null && item.name === "CreateHub")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("hub address:", events[0].args.hub)
|
|
|
|
|
|
|
|
console.log("hub owner:", events[0].args.creator)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
create
|
|
|
|
|
|
|
|
.command("repo")
|
|
|
|
.argument("<uri>", "ex: git3.w3q/repo_name")
|
|
|
|
.argument("<uri>", "ex: git3.w3q/repo_name")
|
|
|
|
.description("create a new repo")
|
|
|
|
.description("create a new repo")
|
|
|
|
.action(async (uri) => {
|
|
|
|
.action(async (uri) => {
|
|
|
|
if (!uri.startsWith("git3://")) {
|
|
|
|
const protocol = await parseGit3URI(uri, { ignoreProtocolHeader: true })
|
|
|
|
uri = "git3://" + uri
|
|
|
|
|
|
|
|
}
|
|
|
|
let isMember = await protocol.hub.membership(protocol.wallet.address)
|
|
|
|
const protocol = await parseGit3URI(uri)
|
|
|
|
if (!isMember) {
|
|
|
|
let owner = await protocol.contract.repoNameToOwner(
|
|
|
|
let hubName = protocol.ns
|
|
|
|
Buffer.from(protocol.repoName)
|
|
|
|
? `${protocol.nsName}.${protocol.nsDomain}`
|
|
|
|
|
|
|
|
: protocol.hubAddress
|
|
|
|
|
|
|
|
console.error(`you are not a member of this hub: ${hubName}`)
|
|
|
|
|
|
|
|
let isPermissionless = await protocol.hub.permissionless()
|
|
|
|
|
|
|
|
if (isPermissionless) {
|
|
|
|
|
|
|
|
console.error(
|
|
|
|
|
|
|
|
`this hub is permissionless, you can join it with: git3 join ${hubName}`
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.error(
|
|
|
|
|
|
|
|
`this hub is not permissionless, you can ask the hub owner to add you as a member`
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let owner = await protocol.hub.repoOwner(Buffer.from(protocol.repoName))
|
|
|
|
|
|
|
|
|
|
|
|
if (owner != "0x0000000000000000000000000000000000000000") {
|
|
|
|
if (owner != "0x0000000000000000000000000000000000000000") {
|
|
|
|
console.error(`repo ${protocol.repoName} already exists`)
|
|
|
|
console.error(`repo ${protocol.repoName} already exists`)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log(
|
|
|
|
|
|
|
|
`creating repo ${protocol.repoName} on ${protocol.netConfig.name}...`
|
|
|
|
console.log(`creating repo ${protocol.repoName} on ${protocol.netConfig.name}...`)
|
|
|
|
)
|
|
|
|
const txManager = new TxManager(protocol.hub, protocol.chainId, protocol.netConfig.txConst)
|
|
|
|
const txManager = new TxManager(
|
|
|
|
let receipt = await txManager.SendCall("createRepo", [Buffer.from(protocol.repoName)])
|
|
|
|
protocol.contract,
|
|
|
|
|
|
|
|
protocol.chainId,
|
|
|
|
console.log(explorerTxUrl(receipt.transactionHash, protocol.netConfig.explorers))
|
|
|
|
protocol.netConfig.txConst
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
let receipt = await txManager.SendCall("createRepo", [
|
|
|
|
|
|
|
|
Buffer.from(protocol.repoName),
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
|
|
protocol.netConfig.explorers &&
|
|
|
|
|
|
|
|
protocol.netConfig.explorers.length > 0
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
|
|
protocol.netConfig.explorers[0].url.replace(/\/+$/, "") +
|
|
|
|
|
|
|
|
"/tx/" +
|
|
|
|
|
|
|
|
receipt.transactionHash
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.log(receipt.transactionHash)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log(`repo ${protocol.repoName} created.`)
|
|
|
|
console.log(`repo ${protocol.repoName} created.`)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
program
|
|
|
|
|
|
|
|
.command("join")
|
|
|
|
|
|
|
|
.argument("<hub>", "hub_name.NS or hub_address:chain_id")
|
|
|
|
|
|
|
|
.description("join a permissionless hub")
|
|
|
|
|
|
|
|
.action(async (hub) => {
|
|
|
|
|
|
|
|
let protocol = await parseGit3URI(hub, { ignoreProtocolHeader: true, skipRepoName: true })
|
|
|
|
|
|
|
|
let isPermissionless = await protocol.hub.permissionless()
|
|
|
|
|
|
|
|
if (!isPermissionless) {
|
|
|
|
|
|
|
|
console.error(`hub ${protocol.hubAddress} is not permissionless`)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const txManager = new TxManager(protocol.hub, protocol.chainId, protocol.netConfig.txConst)
|
|
|
|
|
|
|
|
let receipt = await txManager.SendCall("permissionlessJoin", [])
|
|
|
|
|
|
|
|
console.log(explorerTxUrl(receipt.transactionHash, protocol.netConfig.explorers))
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
program
|
|
|
|
program
|
|
|
|
.command("info")
|
|
|
|
.command("info")
|
|
|
|
.argument("[wallet]", "wallet you want to get info", "default")
|
|
|
|
.argument("[wallet]", "wallet you want to get info", "default")
|
|
|
@ -191,9 +247,7 @@ program
|
|
|
|
console.log(`address: ${address}`)
|
|
|
|
console.log(`address: ${address}`)
|
|
|
|
|
|
|
|
|
|
|
|
for (let [_, net] of Object.entries(network)) {
|
|
|
|
for (let [_, net] of Object.entries(network)) {
|
|
|
|
const provider = new ethers.providers.JsonRpcProvider(
|
|
|
|
const provider = new ethers.providers.JsonRpcProvider(randomRPC(net.rpc))
|
|
|
|
randomRPC(net.rpc)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
const balance = provider.getBalance(address)
|
|
|
|
const balance = provider.getBalance(address)
|
|
|
|
balance.then((res) => {
|
|
|
|
balance.then((res) => {
|
|
|
|
console.log(
|
|
|
|
console.log(
|
|
|
@ -216,11 +270,7 @@ program
|
|
|
|
uri = "git3://" + uri
|
|
|
|
uri = "git3://" + uri
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const protocol = await parseGit3URI(uri, { skipRepoName: true })
|
|
|
|
const protocol = await parseGit3URI(uri, { skipRepoName: true })
|
|
|
|
const txManager = new TxManager(
|
|
|
|
const txManager = new TxManager(protocol.hub, protocol.chainId, protocol.netConfig.txConst)
|
|
|
|
protocol.contract,
|
|
|
|
|
|
|
|
protocol.chainId,
|
|
|
|
|
|
|
|
protocol.netConfig.txConst
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
let nonce = await protocol.wallet.getTransactionCount()
|
|
|
|
let nonce = await protocol.wallet.getTransactionCount()
|
|
|
|
console.log(`current nonce: ${nonce}`)
|
|
|
|
console.log(`current nonce: ${nonce}`)
|
|
|
|
await txManager.clearPendingNonce(num)
|
|
|
|
await txManager.clearPendingNonce(num)
|
|
|
|