Skip to content

Commit

Permalink
Merge pull request #558 from tonlabs/cli-as-module
Browse files Browse the repository at this point in the history
cli as module
  • Loading branch information
d3p authored Sep 13, 2023
2 parents eacc88a + 5ad4089 commit ba2becb
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 153 deletions.
138 changes: 138 additions & 0 deletions packages/cli/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/usr/bin/env node

import { program } from "commander"
import { TonClient } from "@eversdk/core"
import { libNode } from "@eversdk/lib-node"
import { toString as qrcode } from "qrcode"
import { promisify } from "util"
import dotenv from "dotenv"

import { myParseInt, getEnv } from "./utils"
import { graphql } from "./graphql"
import { kamikadze } from "./kamikadze"
import {
touch,
DEFAULT_TOUCH_MAX_BALANCE,
DEFAULT_TOUCH_TRY_COUNT,
DEFAULT_TOUCH_TRY_SLEEP,
} from "./touch"
import { compile } from "./compile"
import { DEFAULT_TOPUP_BALANCE, deploy } from "./giver"

dotenv.config()

TonClient.useBinaryLibrary(libNode)

program
.name("evercloud")
.description("Evercloud CLI")
.version(getEnv("npm_package_version") as string)

program.option("-d, --debug", "Output debug information (time)")

program
.command("compile")
.alias("c")
.argument("<string>", "Path to Contract source file (.sol)")
.description(
"Compile contract, wrap it into js, generate d.ts (depends on `npx` tool, should be in PATH)",
)
.action(compile)

program.command("deploy").alias("d").description("Deploy giver").action(deploy)

program
.command("graphql")
.alias("q")
.argument("<string>", "query text (also can be subscription or mutation)")
.description("Sending a query to a GraphQL endpoint.")
.option(
"-c, --count <number>",
"Specify the number of events to wait.",
myParseInt,
0,
)
.action(graphql)

program
.command("kamikadze")
.alias("k")
.description(
"Run the Kamikaze contract, which triggers the self-destruct process by calling the `sendAllMoney` function.",
)
.option(
"-v, --value <number>",
"Top up the Kamikaze contract before deploying it in nanotokens.",
myParseInt,
DEFAULT_TOPUP_BALANCE,
)
.action(kamikadze)

program
.command("qrcode")
.alias("qr")
.argument("<string>")
.description(
"Generate a QR code using the provided text argument and output it to the console.",
)
.action(async req => {
console.log(await promisify(qrcode)(req))
})

program
.command("touch")
.alias("t")
.description(
"Run the Touch contract, which increases local state variable timestamp.",
)
.option(
"-v, --value <number>",
"Top up the Touch contract before deploying it in nanotokens.",
myParseInt,
DEFAULT_TOUCH_MAX_BALANCE,
)
.option(
"-c, --try-count <number>",
"If the GraphQL response does not contain a valid value, retry the request a maximum of `tryCount` times.",
myParseInt,
DEFAULT_TOUCH_TRY_COUNT,
)
.option(
"-s, --try-sleep <number>",
"If the GraphQL response does not contain a valid value, sleep for `trySleep` milisecodes before next try.",
myParseInt,
DEFAULT_TOUCH_TRY_SLEEP,
)
.action(touch)

program.addHelpText(
"after",
`
Examples:
$ evercloud c ./contracts/Kamikadze.sol
$ evercloud q "query{blockchain{blocks(last:1 workchain:-1){edges{node{seq_no hash}}}}}"
$ evercloud q "subscription{blocks(filter:{workchain_id:{eq:-1}}){seq_no id}}"
$ EVERCLOUD_GIVER_TYPE=v2 TON_NETWORK_ADDRESS=https://devnet.evercloud.dev/<ProjectId> TON_GIVER_ADDRESS=<address> TON_GIVER_SECRET=<privateKey> evercloud k
$ evercloud qr 0:66cb703cd63dd0b9eafbce702a9f838211ba1ea5ccce101dc81b98114d824b8a
$ evercloud t -d
`,
)

program
.parseAsync(process.argv)
.then(cmd => {
if (cmd.opts().debug) {
console.log(`finished in ${process.uptime().toFixed(2)}s`)
}
process.exit(0)
})
.catch(error => {
console.dir(error, { showHidden: false, depth: null })
process.exit(1)
})
144 changes: 6 additions & 138 deletions packages/cli/index.ts
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,138 +1,6 @@
#!/usr/bin/env node

import { program } from "commander"
import { TonClient } from "@eversdk/core"
import { libNode } from "@eversdk/lib-node"
import { toString as qrcode } from "qrcode"
import { promisify } from "util"
import dotenv from "dotenv"

import { myParseInt, getEnv } from "./utils"
import { graphql } from "./graphql"
import { kamikadze } from "./kamikadze"
import {
touch,
DEFAULT_TOUCH_MAX_BALANCE,
DEFAULT_TOUCH_TRY_COUNT,
DEFAULT_TOUCH_TRY_SLEEP,
} from "./touch"
import { compile } from "./compile"
import { DEFAULT_TOPUP_BALANCE, deploy } from "./giver"

dotenv.config()

TonClient.useBinaryLibrary(libNode)

program
.name("evercloud")
.description("Evercloud CLI")
.version(getEnv("npm_package_version") as string)

program.option("-d, --debug", "Output debug information (time)")

program
.command("compile")
.alias("c")
.argument("<string>", "Path to Contract source file (.sol)")
.description(
"Compile contract, wrap it into js, generate d.ts (depends on `npx` tool, should be in PATH)",
)
.action(compile)

program.command("deploy").alias("d").description("Deploy giver").action(deploy)

program
.command("graphql")
.alias("q")
.argument("<string>", "query text (also can be subscription or mutation)")
.description("Sending a query to a GraphQL endpoint.")
.option(
"-c, --count <number>",
"Specify the number of events to wait.",
myParseInt,
0,
)
.action(graphql)

program
.command("kamikadze")
.alias("k")
.description(
"Run the Kamikaze contract, which triggers the self-destruct process by calling the `sendAllMoney` function.",
)
.option(
"-v, --value <number>",
"Top up the Kamikaze contract before deploying it in nanotokens.",
myParseInt,
DEFAULT_TOPUP_BALANCE,
)
.action(kamikadze)

program
.command("qrcode")
.alias("qr")
.argument("<string>")
.description(
"Generate a QR code using the provided text argument and output it to the console.",
)
.action(async req => {
console.log(await promisify(qrcode)(req))
})

program
.command("touch")
.alias("t")
.description(
"Run the Touch contract, which increases local state variable timestamp.",
)
.option(
"-v, --value <number>",
"Top up the Touch contract before deploying it in nanotokens.",
myParseInt,
DEFAULT_TOUCH_MAX_BALANCE,
)
.option(
"-c, --try-count <number>",
"If the GraphQL response does not contain a valid value, retry the request a maximum of `tryCount` times.",
myParseInt,
DEFAULT_TOUCH_TRY_COUNT,
)
.option(
"-s, --try-sleep <number>",
"If the GraphQL response does not contain a valid value, sleep for `trySleep` milisecodes before next try.",
myParseInt,
DEFAULT_TOUCH_TRY_SLEEP,
)
.action(touch)

program.addHelpText(
"after",
`
Examples:
$ evercloud c ./contracts/Kamikadze.sol
$ evercloud q "query{blockchain{blocks(last:1 workchain:-1){edges{node{seq_no hash}}}}}"
$ evercloud q "subscription{blocks(filter:{workchain_id:{eq:-1}}){seq_no id}}"
$ EVERCLOUD_GIVER_TYPE=v2 TON_NETWORK_ADDRESS=https://devnet.evercloud.dev/<ProjectId> TON_GIVER_ADDRESS=<address> TON_GIVER_SECRET=<privateKey> evercloud k
$ evercloud qr 0:66cb703cd63dd0b9eafbce702a9f838211ba1ea5ccce101dc81b98114d824b8a
$ evercloud t -d
`,
)

program
.parseAsync(process.argv)
.then(cmd => {
if (cmd.opts().debug) {
console.log(`finished in ${process.uptime().toFixed(2)}s`)
}
process.exit(0)
})
.catch(error => {
console.dir(error, { showHidden: false, depth: null })
process.exit(1)
})
export * from "./compile"
export * from "./giver"
export * from "./graphql"
export * from "./kamikadze"
export * from "./touch"
export * from "./utils"
14 changes: 7 additions & 7 deletions packages/cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@
"test": "npm run clean; npx ts-node index.ts"
},
"bin": {
"evercloud": "./index.js"
"evercloud": "./cli.js"
},
"files": [
"index.js",
"cli.js",
"compile.js",
"giver.js",
"graphql.js",
Expand Down
18 changes: 11 additions & 7 deletions packages/cli/touch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Account } from "@eversdk/appkit"
import { getDefaultEndpoints, sleep } from "./utils"
import { Giver, DEFAULT_TOPUP_BALANCE } from "./giver"
import { performance } from "node:perf_hooks"
import { TonClient } from "@eversdk/core"
import { TonClient, Signer } from "@eversdk/core"
import * as Touch from "./contracts/Touch.js"

export const DEFAULT_TOUCH_MAX_BALANCE = 100 * 1e9
Expand All @@ -13,6 +13,7 @@ export async function touch(options: {
value: number
tryCount: number
trySleep: number
signer: Signer
}) {
const sdk = new TonClient({
abi: {
Expand All @@ -28,14 +29,17 @@ export async function touch(options: {
const giver = await Giver.create(sdk)
const touch = new Account(Touch, {
client: sdk,
signer: giver.account.signer,
signer: options.signer ?? giver.account.signer,
})
const touchAccount = await touch.getAccount()
const { balance } = touchAccount
const balance = await touch.getBalance()
const address = await touch.getAddress()

if (BigInt(balance ?? 0) < DEFAULT_TOPUP_BALANCE) {
await giver.sendTo(address, options.value)
if (balance && BigInt(balance) < DEFAULT_TOPUP_BALANCE) {
await giver.sendTo(address, options.value ?? DEFAULT_TOUCH_MAX_BALANCE)
console.log("Touch topup:", address)
} else if (!balance) {
await giver.sendTo(address, DEFAULT_TOPUP_BALANCE)
console.log("Touch topup:", address)
}

Expand All @@ -57,7 +61,7 @@ export async function touch(options: {
console.log(`Touch ok: ${response.transaction.id}`)

let tryCounter = 0
while (tryCounter < options.tryCount) {
while (tryCounter < options.tryCount ?? DEFAULT_TOUCH_TRY_COUNT) {
touch.refresh() // Force to take frech boc from graphql
const balanceAfter = BigInt((await touch.getBalance()) ?? 0)
const timestampNew = BigInt(
Expand Down Expand Up @@ -85,7 +89,7 @@ export async function touch(options: {
console.log(
`Touch local state has not been updated (try: ${++tryCounter})`,
)
await sleep(options.trySleep)
await sleep(options.trySleep ?? DEFAULT_TOUCH_TRY_SLEEP)
}
}
}
Expand Down

0 comments on commit ba2becb

Please sign in to comment.