mirror of git3://git3.w3q/git3-cli
parent
b6e6286b23
commit
c2956f0c41
@ -0,0 +1,4 @@
|
||||
{
|
||||
"prettier.tabWidth": 4,
|
||||
"vetur.format.options.tabSize": 4
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
import { ethers } from "ethers"
|
||||
import nameServices from "../config/name-services.js"
|
||||
import { ETHStorage } from "../storage/ETHStorage.js"
|
||||
import { SLIStorage } from "../storage/SLIStorage.js"
|
||||
import { getWallet, randomRPC, setupContract } from "./wallet.js"
|
||||
import network from "../config/evm-network.js"
|
||||
import abis from "../config/abis.js"
|
||||
|
||||
export type Git3Protocol = {
|
||||
sender: string
|
||||
senderAddress: string
|
||||
hubAddress: string
|
||||
repoName: string
|
||||
chainId: number
|
||||
netConfig: Record<string, any>
|
||||
wallet: ethers.Wallet
|
||||
contract: ethers.Contract
|
||||
storageClass: any
|
||||
ns?: Record<string, any>
|
||||
nsName?: string
|
||||
nsDomain?: string
|
||||
}
|
||||
|
||||
type Option = {
|
||||
skipRepoName: boolean
|
||||
}
|
||||
|
||||
export function parseGit3URI(
|
||||
uri: string,
|
||||
option: Option = { skipRepoName: false }
|
||||
): Git3Protocol {
|
||||
const url = new URL(uri)
|
||||
let sender = url.username || "default"
|
||||
let chainId = url.port ? parseInt(url.port) : null
|
||||
let hub = url.hostname
|
||||
let hubAddress
|
||||
let nsName, nsDomain, ns
|
||||
if (!hub) throw new Error("invalid git3 uri, no hub address")
|
||||
let repoName = url.pathname.slice(1)
|
||||
if (!option.skipRepoName && !repoName)
|
||||
throw new Error("invalid git3 uri, no repo name")
|
||||
|
||||
if (hub.indexOf(".") < 0) {
|
||||
if (url.hostname.startsWith("0x")) {
|
||||
hubAddress = url.hostname
|
||||
} else {
|
||||
throw new Error("invalid git3 uri, hub must be NS or address")
|
||||
}
|
||||
} else {
|
||||
;[nsName, nsDomain] = url.hostname.split(".")
|
||||
ns = nameServices[nsDomain]
|
||||
if (!ns) throw new Error("invalid name service")
|
||||
chainId = chainId || ns.chainId
|
||||
// Todo: resolve name service
|
||||
// hubAddress = ns.resolver()
|
||||
}
|
||||
|
||||
if (!chainId) throw new Error("invalid git3 uri, no chainId")
|
||||
|
||||
let netConfig = network[chainId]
|
||||
if (!netConfig) throw new Error("invalid chainId")
|
||||
|
||||
if (!hubAddress) hubAddress = netConfig.contracts.git3
|
||||
|
||||
let wallet = getWallet(sender)
|
||||
|
||||
let senderAddress = wallet.address
|
||||
|
||||
// route to different storage
|
||||
let storageClass, abi
|
||||
if (chainId == 3334) {
|
||||
storageClass = ETHStorage
|
||||
abi = abis.ETHStorage
|
||||
} else {
|
||||
storageClass = SLIStorage
|
||||
abi = abis.SLIStorage
|
||||
}
|
||||
let rpc = randomRPC(netConfig.rpc)
|
||||
const provider = new ethers.providers.JsonRpcProvider(rpc)
|
||||
|
||||
let contract = setupContract(provider, hubAddress, abi, wallet)
|
||||
wallet = wallet.connect(contract.provider)
|
||||
|
||||
return {
|
||||
sender,
|
||||
senderAddress,
|
||||
hubAddress,
|
||||
repoName,
|
||||
chainId,
|
||||
netConfig,
|
||||
wallet,
|
||||
contract,
|
||||
storageClass,
|
||||
ns,
|
||||
nsName,
|
||||
nsDomain,
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
import { mkdirSync, readFileSync } from "fs"
|
||||
import { ethers } from "ethers"
|
||||
|
||||
export function getWallet(wallet: string | null = "default"): ethers.Wallet {
|
||||
if (!wallet) wallet = "default"
|
||||
|
||||
// Todo: 0xaddress find wallet
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
const content = readFileSync(`${keyPath}/${wallet}`).toString()
|
||||
const [walletType, key] = content.split("\n")
|
||||
|
||||
let etherWallet =
|
||||
walletType === "privateKey"
|
||||
? new ethers.Wallet(key)
|
||||
: ethers.Wallet.fromMnemonic(key)
|
||||
|
||||
return etherWallet
|
||||
}
|
||||
|
||||
export function setupContract(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
hubAddress: string,
|
||||
abi: string,
|
||||
wallet: ethers.Wallet
|
||||
): ethers.Contract {
|
||||
|
||||
let contract = new ethers.Contract(hubAddress, abi, provider)
|
||||
wallet = wallet.connect(provider)
|
||||
contract = contract.connect(wallet)
|
||||
|
||||
return contract
|
||||
}
|
||||
|
||||
export function randomRPC(rpcs: string[]): string {
|
||||
return rpcs[Math.floor(Math.random() * rpcs.length)]
|
||||
}
|
@ -1,234 +1,278 @@
|
||||
import { mkdirSync, readdirSync, readFileSync, writeFileSync, rmSync, existsSync } from 'fs'
|
||||
import { ethers } from 'ethers'
|
||||
import { Command } from 'commander'
|
||||
import bip39 from 'bip39'
|
||||
import inquirer from 'inquirer'
|
||||
import parse from 'parse-git-config'
|
||||
import { importActions, generateActions } from './actions.js'
|
||||
import abis from "../config/abis.js"
|
||||
import { mkdirSync, readdirSync, readFileSync, writeFileSync, rmSync } from "fs"
|
||||
import { ethers } from "ethers"
|
||||
import { Command } from "commander"
|
||||
import bip39 from "bip39"
|
||||
import inquirer from "inquirer"
|
||||
import { importActions, generateActions } from "./actions.js"
|
||||
import network from "../config/evm-network.js"
|
||||
import { getWallet, randomRPC } from "../common/wallet.js"
|
||||
import { parseGit3URI } from "../common/git3-protocol.js"
|
||||
import { TxManager } from "../common/tx-manager.js"
|
||||
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')
|
||||
|
||||
program.command('generate')
|
||||
.alias('gen')
|
||||
.alias('new')
|
||||
.description('generate a cryto wallet to use git3')
|
||||
.action(() => {
|
||||
inquirer.prompt(generateActions).then(answers => {
|
||||
const { keyType, name } = answers
|
||||
const walletType = keyType === 'private key' ? 'privateKey' : 'mnemonic'
|
||||
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
if (readdirSync(keyPath).includes(name)) {
|
||||
console.error(`wallet ${name} already exists`)
|
||||
return
|
||||
}
|
||||
|
||||
const mnemonic = bip39.generateMnemonic()
|
||||
const wallet = keyType === 'private key'
|
||||
? ethers.Wallet.createRandom()
|
||||
: ethers.Wallet.fromMnemonic(mnemonic)
|
||||
|
||||
const content = `${walletType}\n${keyType === 'private key' ? wallet.privateKey : mnemonic}\n`
|
||||
writeFileSync(`${keyPath}/${name}`, content)
|
||||
return
|
||||
})
|
||||
})
|
||||
|
||||
program.command('list', { isDefault: true })
|
||||
.alias('ls')
|
||||
.description('list all wallets in user folder ~/.git3/keys')
|
||||
.option('-r, --raw', 'output raw wallet data with pravate key / mnemonic')
|
||||
.action(params => {
|
||||
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
const wallets = readdirSync(keyPath)
|
||||
|
||||
if (wallets.length === 0) {
|
||||
console.log('No wallet found, you can generate one use <git3 new>')
|
||||
}
|
||||
|
||||
wallets.forEach(file => {
|
||||
const content = readFileSync(`${keyPath}/${file}`).toString()
|
||||
|
||||
|
||||
if (params.raw) {
|
||||
console.log(`[${file}]`)
|
||||
console.log(` ${content.split('\n')[0]} - ${content.split('\n')[1]}`)
|
||||
console.log('\t')
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`[${file}]`)
|
||||
const [walletType, key] = content.split('\n')
|
||||
const etherWallet = walletType === 'privateKey'
|
||||
? new ethers.Wallet(key)
|
||||
: ethers.Wallet.fromMnemonic(key)
|
||||
const address = etherWallet.address
|
||||
console.log(`address: ${address}`)
|
||||
console.log('\t')
|
||||
})
|
||||
})
|
||||
|
||||
program.command('import')
|
||||
.description('import a wallet from a private key or mnemonic')
|
||||
.action(() => {
|
||||
inquirer.prompt(importActions).then(answers => {
|
||||
const { keyType, key, name } = answers
|
||||
const walletType = keyType === 'private key' ? 'privateKey' : 'mnemonic'
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
if (readdirSync(keyPath).includes(name)) {
|
||||
console.error(`wallet ${name} already exists`)
|
||||
return
|
||||
}
|
||||
|
||||
const content = `${walletType}\n${key}\n`
|
||||
writeFileSync(`${keyPath}/${name}`, content)
|
||||
return
|
||||
})
|
||||
})
|
||||
|
||||
program.command('delete')
|
||||
.description('delete a wallet')
|
||||
.action(() => {
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
const wallets = readdirSync(keyPath)
|
||||
|
||||
if (wallets.length === 0) {
|
||||
console.error('No wallet found, you can generate one with `git3 generate`')
|
||||
return
|
||||
}
|
||||
|
||||
inquirer.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'wallet',
|
||||
message: 'Select wallet to delete',
|
||||
choices: wallets
|
||||
}
|
||||
]).then(answers => {
|
||||
const { wallet } = answers
|
||||
rmSync(`${keyPath}/${wallet}`)
|
||||
.command("generate")
|
||||
.alias("gen")
|
||||
.alias("new")
|
||||
.description("generate a cryto wallet to use git3")
|
||||
.action(() => {
|
||||
inquirer.prompt(generateActions).then((answers) => {
|
||||
const { keyType, name } = answers
|
||||
const walletType =
|
||||
keyType === "private key" ? "privateKey" : "mnemonic"
|
||||
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
if (readdirSync(keyPath).includes(name)) {
|
||||
console.error(`wallet ${name} already exists`)
|
||||
return
|
||||
}
|
||||
|
||||
const mnemonic = bip39.generateMnemonic()
|
||||
const wallet =
|
||||
keyType === "private key"
|
||||
? ethers.Wallet.createRandom()
|
||||
: ethers.Wallet.fromMnemonic(mnemonic)
|
||||
|
||||
const content = `${walletType}\n${
|
||||
keyType === "private key" ? wallet.privateKey : mnemonic
|
||||
}\n`
|
||||
writeFileSync(`${keyPath}/${name}`, content)
|
||||
return
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
program.command('create')
|
||||
.argument('[wallet]', 'wallet to use', 'default')
|
||||
.argument('[repo]', 'repo name to create')
|
||||
.description('create a new repo')
|
||||
.action((wallet, repo) => {
|
||||
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
const content = readFileSync(`${keyPath}/${wallet}`).toString()
|
||||
|
||||
const [walletType, key] = content.split('\n')
|
||||
const provider = new ethers.providers.JsonRpcProvider('https://galileo.web3q.io:8545');
|
||||
|
||||
let etherWallet = walletType === 'privateKey'
|
||||
? new ethers.Wallet(key)
|
||||
: ethers.Wallet.fromMnemonic(key)
|
||||
|
||||
etherWallet = etherWallet.connect(provider)
|
||||
let net = network[3334]
|
||||
const contract = new ethers.Contract(
|
||||
net.contracts.git3,
|
||||
abis.ETHStorage,
|
||||
etherWallet)
|
||||
|
||||
program
|
||||
.command("list", { isDefault: true })
|
||||
.alias("ls")
|
||||
.description("list all wallets in user folder ~/.git3/keys")
|
||||
.option("-r, --raw", "output raw wallet data with pravate key / mnemonic")
|
||||
.action((params) => {
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
const wallets = readdirSync(keyPath)
|
||||
|
||||
if (wallets.length === 0) {
|
||||
console.log("No wallet found, you can generate one use <git3 new>")
|
||||
}
|
||||
|
||||
contract.repoNameToOwner(Buffer.from(repo))
|
||||
.then((res: any) => { console.log(res) })
|
||||
.catch((err: any) => { console.error(err) })
|
||||
contract.createRepo(Buffer.from(repo))
|
||||
.then((res: any) => { console.log(res) })
|
||||
.catch((err: any) => { console.error(err) })
|
||||
wallets.forEach((file) => {
|
||||
const content = readFileSync(`${keyPath}/${file}`).toString()
|
||||
|
||||
if (params.raw) {
|
||||
console.log(`[${file}]`)
|
||||
console.log(
|
||||
` ${content.split("\n")[0]} - ${content.split("\n")[1]}`
|
||||
)
|
||||
console.log("\t")
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`[${file}]`)
|
||||
const [walletType, key] = content.split("\n")
|
||||
const etherWallet =
|
||||
walletType === "privateKey"
|
||||
? new ethers.Wallet(key)
|
||||
: ethers.Wallet.fromMnemonic(key)
|
||||
const address = etherWallet.address
|
||||
console.log(`address: ${address}`)
|
||||
console.log("\t")
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
program
|
||||
.command("import")
|
||||
.description("import a wallet from a private key or mnemonic")
|
||||
.action(() => {
|
||||
inquirer.prompt(importActions).then((answers) => {
|
||||
const { keyType, key, name } = answers
|
||||
const walletType =
|
||||
keyType === "private key" ? "privateKey" : "mnemonic"
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
if (readdirSync(keyPath).includes(name)) {
|
||||
console.error(`wallet ${name} already exists`)
|
||||
return
|
||||
}
|
||||
|
||||
const content = `${walletType}\n${key}\n`
|
||||
writeFileSync(`${keyPath}/${name}`, content)
|
||||
return
|
||||
})
|
||||
})
|
||||
|
||||
program.command('info')
|
||||
.argument('[wallet]', 'wallet you want to get info', 'default')
|
||||
.description('get info of a wallet')
|
||||
.action(wallet => {
|
||||
program
|
||||
.command("delete")
|
||||
.description("delete a wallet")
|
||||
.action(() => {
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
const wallets = readdirSync(keyPath)
|
||||
|
||||
if (wallets.length === 0) {
|
||||
console.error(
|
||||
"No wallet found, you can generate one with `git3 generate`"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
inquirer
|
||||
.prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "wallet",
|
||||
message: "Select wallet to delete",
|
||||
choices: wallets,
|
||||
},
|
||||
])
|
||||
.then((answers) => {
|
||||
const { wallet } = answers
|
||||
rmSync(`${keyPath}/${wallet}`)
|
||||
})
|
||||
})
|
||||
|
||||
const content = readFileSync(`${keyPath}/${wallet}`).toString()
|
||||
const [walletType, key] = content.split('\n')
|
||||
const provider = new ethers.providers.JsonRpcProvider('https://galileo.web3q.io:8545');
|
||||
program
|
||||
.command("create")
|
||||
.argument("<uri>", "ex: default@git3.w3q/repo_name")
|
||||
.description("create a new repo")
|
||||
.action(async (uri) => {
|
||||
if (!uri.startsWith("git3://")) {
|
||||
uri = "git3://" + uri
|
||||
}
|
||||
const protocol = parseGit3URI(uri)
|
||||
let owner = await protocol.contract.repoNameToOwner(
|
||||
Buffer.from(protocol.repoName)
|
||||
)
|
||||
|
||||
if (owner != "0x0000000000000000000000000000000000000000") {
|
||||
console.error(`repo ${protocol.repoName} already exists`)
|
||||
return
|
||||
}
|
||||
console.log(
|
||||
`creating repo ${protocol.repoName} on ${protocol.netConfig.name}...`
|
||||
)
|
||||
const txManager = new TxManager(
|
||||
protocol.contract,
|
||||
protocol.chainId,
|
||||
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.`)
|
||||
})
|
||||
|
||||
let etherWallet = walletType === 'privateKey'
|
||||
? new ethers.Wallet(key)
|
||||
: ethers.Wallet.fromMnemonic(key)
|
||||
program
|
||||
.command("info")
|
||||
.argument("[wallet]", "wallet you want to get info", "default")
|
||||
.description("get info of a wallet")
|
||||
.action((wallet) => {
|
||||
let etherWallet = getWallet(wallet)
|
||||
|
||||
etherWallet = etherWallet.connect(provider)
|
||||
const address = etherWallet.address
|
||||
const address = etherWallet.address
|
||||
|
||||
etherWallet.getBalance()
|
||||
.then(balance => {
|
||||
console.log(`wallet: ${wallet}`)
|
||||
console.log(`address: ${address}`)
|
||||
console.log(`balance: ${ethers.utils.formatUnits(balance)} eth`)
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
return
|
||||
})
|
||||
})
|
||||
|
||||
program.command('set-wallet')
|
||||
.alias('set')
|
||||
.argument('<git3>', 'git3 remote')
|
||||
.argument('[wallet]', 'wallet you want to bind', 'default')
|
||||
.description('bind git3 remotes with a wallet')
|
||||
.action((git3, wallet) => {
|
||||
const currentConfig = parse.sync()
|
||||
|
||||
const existingRemote = currentConfig[`remote "${git3}"`]
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
if (!existsSync(`${keyPath}/${wallet}`)) {
|
||||
console.error(`wallet ${wallet} not found, use <git3 new> to generate one`)
|
||||
return
|
||||
}
|
||||
|
||||
if (existingRemote) {
|
||||
const newConfig = {
|
||||
...currentConfig,
|
||||
[`remote "${git3}"`]: {
|
||||
...existingRemote,
|
||||
wallet
|
||||
|
||||
for (let [_, net] of Object.entries(network)) {
|
||||
const provider = new ethers.providers.JsonRpcProvider(
|
||||
randomRPC(net.rpc)
|
||||
)
|
||||
const balance = provider.getBalance(address)
|
||||
balance.then((res) => {
|
||||
console.log(
|
||||
`[${net.name}] balance: ${ethers.utils.formatUnits(
|
||||
res,
|
||||
net.nativeCurrency.decimals
|
||||
)} ${net.nativeCurrency.symbol}`
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(newConfig)
|
||||
// const writer = createWriteStream('config', 'w')
|
||||
let newConfigText = ''
|
||||
Object.keys(newConfig).forEach(key => {
|
||||
newConfigText += `[${key}]\n`
|
||||
Object.keys(newConfig[key]).forEach(subKey => {
|
||||
newConfigText += `\t${subKey} = ${newConfig[key][subKey]}\n`
|
||||
})
|
||||
})
|
||||
let path = parse.resolveConfigPath("global") || ""
|
||||
writeFileSync(path, newConfigText)
|
||||
} else {
|
||||
console.error(`remote ${git3} not found`)
|
||||
console.error('you can add a remote with `git remote add <name> <url>')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
program
|
||||
.command("clear")
|
||||
.description("clear pending nonce")
|
||||
.argument("<uri>", "ex: default@git3.w3q")
|
||||
.argument("[num]", "number of pending nonce to clear", 1)
|
||||
.action(async (uri,num) => {
|
||||
if (!uri.startsWith("git3://")) {
|
||||
uri = "git3://" + uri
|
||||
}
|
||||
const protocol = parseGit3URI(uri, { skipRepoName: true })
|
||||
const txManager = new TxManager(
|
||||
protocol.contract,
|
||||
protocol.chainId,
|
||||
protocol.netConfig.txConst
|
||||
)
|
||||
let nonce = await protocol.wallet.getTransactionCount()
|
||||
console.log(`current nonce: ${nonce}`)
|
||||
await txManager.clearPendingNonce(num)
|
||||
})
|
||||
|
||||
// Todo: set-wallet temporarily useless
|
||||
// program
|
||||
// .command("set-wallet")
|
||||
// .alias("set")
|
||||
// .argument("<git3>", "git3 remote")
|
||||
// .argument("[wallet]", "wallet you want to bind", "default")
|
||||
// .description("bind git3 remotes with a wallet")
|
||||
// .action((git3, wallet) => {
|
||||
// const currentConfig = parse.sync()
|
||||
|
||||
// const existingRemote = currentConfig[`remote "${git3}"`]
|
||||
// const keyPath = process.env.HOME + "/.git3/keys"
|
||||
// mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
// if (!existsSync(`${keyPath}/${wallet}`)) {
|
||||
// console.error(
|
||||
// `wallet ${wallet} not found, use <git3 new> to generate one`
|
||||
// )
|
||||
// return
|
||||
// }
|
||||
|
||||
// if (existingRemote) {
|
||||
// const newConfig = {
|
||||
// ...currentConfig,
|
||||
// [`remote "${git3}"`]: {
|
||||
// ...existingRemote,
|
||||
// wallet,
|
||||
// },
|
||||
// }
|
||||
|
||||
// // console.log(newConfig)
|
||||
// // const writer = createWriteStream('config', 'w')
|
||||
// let newConfigText = ""
|
||||
// Object.keys(newConfig).forEach((key) => {
|
||||
// newConfigText += `[${key}]\n`
|
||||
// Object.keys(newConfig[key]).forEach((subKey) => {
|
||||
// newConfigText += `\t${subKey} = ${newConfig[key][subKey]}\n`
|
||||
// })
|
||||
// })
|
||||
// let path = parse.resolveConfigPath("global") || ""
|
||||
// writeFileSync(path, newConfigText)
|
||||
// } else {
|
||||
// console.error(`remote ${git3} not found`)
|
||||
// console.error(
|
||||
// "you can add a remote with `git remote add <name> <url>"
|
||||
// )
|
||||
// }
|
||||
// })
|
||||
|
||||
program.parse()
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { mkdirSync, readFileSync } from "fs"
|
||||
import { ethers } from 'ethers'
|
||||
|
||||
export function getWallet(sender: string | null): ethers.Wallet {
|
||||
// Todo: according sender address to select wallet, if sender==null then use default wallet
|
||||
const wallet = 'default'
|
||||
|
||||
const keyPath = process.env.HOME + "/.git3/keys"
|
||||
mkdirSync(keyPath, { recursive: true })
|
||||
|
||||
const content = readFileSync(`${keyPath}/${wallet}`).toString()
|
||||
const [walletType, key] = content.split('\n')
|
||||
|
||||
let etherWallet = walletType === 'privateKey'
|
||||
? new ethers.Wallet(key)
|
||||
: ethers.Wallet.fromMnemonic(key)
|
||||
|
||||
return etherWallet
|
||||
}
|
Loading…
Reference in new issue