├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitbook.yaml
├── .github
└── workflows
│ └── npmpublish.yml
├── .gitignore
├── .npmignore
├── .prettierrc
├── .vscode
├── extensions.json
├── settings.json
└── tasks.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets
└── everdev.png
├── ci
├── Jenkinsfile
├── gitbook
│ └── Jenkinsfile
└── jenkins
│ └── Jenkinsfile
├── cli.js
├── contracts
├── GiverV1.abi.json
├── GiverV2.abi.json
├── GiverV2.tvc
├── GiverV3.abi.json
├── GiverV3.sol
├── GiverV3.tvc
├── HelloWallet.abi.json
├── HelloWallet.sol
├── HelloWallet.tvc
├── MsigV2.abi.json
├── MsigV2.sol
├── MsigV2.tvc
├── SafeMultisigWallet.abi.json
├── SafeMultisigWallet.keys.json
├── SafeMultisigWallet.tvc
├── SetcodeMultisigWallet.abi.json
└── seGiver.keys.json
├── docs
├── .gitbook
│ └── assets
│ │ ├── Everscale Logo.png
│ │ ├── Everscale Logo.svg
│ │ └── vf-dev-program.png
├── SUMMARY.md
├── command-line-interface
│ ├── c.md
│ ├── contract-management.md
│ ├── debrowser.md
│ ├── evernode-platform-startup-edition-se.md
│ ├── network-tool.md
│ ├── sdk.md
│ ├── signer-tool.md
│ ├── sold.md
│ ├── solidity-compiler-driver.md
│ ├── solidity.md
│ └── testsuite4.md
├── guides
│ ├── creating-controller.md
│ └── quick-start.md
├── troubleshooting.md
├── use-in-js-applications.md
└── view-controller-info.md
├── jest.config.js
├── package.json
├── src
├── __tests__
│ ├── addProjectId.ts
│ ├── checkArgs.ts
│ ├── checkNewVersion.ts
│ ├── contracts.ts
│ ├── data
│ │ ├── contracts-input-alone.json
│ │ └── contracts-input.json
│ ├── init.ts
│ ├── network.ts
│ ├── parser.ts
│ ├── se.ts
│ ├── signer.ts
│ ├── sol.ts
│ └── wrap.ts
├── cli
│ └── index.ts
├── controllers
│ ├── clang
│ │ ├── components.ts
│ │ ├── index.ts
│ │ └── snippets.ts
│ ├── contract
│ │ ├── accounts.ts
│ │ ├── index.ts
│ │ ├── param-parser.ts
│ │ └── run.ts
│ ├── debrowser
│ │ ├── command
│ │ │ ├── interfaces.ts
│ │ │ ├── start.ts
│ │ │ ├── stop.ts
│ │ │ └── version.ts
│ │ ├── index.ts
│ │ └── installer.ts
│ ├── ever-cli
│ │ ├── components.ts
│ │ └── index.ts
│ ├── index.ts
│ ├── js
│ │ ├── index.ts
│ │ ├── installer.ts
│ │ ├── snippets.ts
│ │ └── wrap.ts
│ ├── network
│ │ ├── giver.ts
│ │ ├── index.ts
│ │ └── registry.ts
│ ├── se
│ │ ├── commands.ts
│ │ ├── index.ts
│ │ └── registry.ts
│ ├── signer
│ │ ├── index.ts
│ │ └── registry.ts
│ ├── sold
│ │ ├── components.ts
│ │ └── index.ts
│ ├── solidity
│ │ ├── components.ts
│ │ ├── index.ts
│ │ └── snippets.ts
│ ├── ts
│ │ ├── create.ts
│ │ ├── index.ts
│ │ ├── inspect.ts
│ │ └── run.ts
│ └── ts4
│ │ ├── components.ts
│ │ ├── index.ts
│ │ └── snippets.ts
├── core
│ ├── component.ts
│ ├── docker.ts
│ ├── index.ts
│ ├── known-contracts.ts
│ ├── solFileResolvers.ts
│ └── utils.ts
├── everdev
│ ├── checkNewVersion.ts
│ ├── help.ts
│ ├── info.ts
│ └── update.ts
├── index.ts
├── rewriteKnownErrors.ts
└── server
│ └── api
│ └── tondev.graphql
├── tsconfig.build.json
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # /node_modules/* in the project root is ignored by default
2 | # build artefacts
3 | dist/*
4 | coverage/*
5 | # data definition files
6 | **/*.d.ts
7 | # 3rd party libs
8 | /src/public/
9 | # custom definition files
10 | /src/types/
11 |
12 | cli.js
13 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: "@typescript-eslint/parser",
4 | parserOptions: {
5 | project: "./tsconfig.json",
6 | tsconfigRootDir: __dirname,
7 | },
8 | plugins: ["@typescript-eslint", "prettier", "jest"],
9 | extends: [
10 | "eslint:recommended",
11 | "plugin:@typescript-eslint/recommended",
12 | // "plugin:@typescript-eslint/recommended-requiring-type-checking",
13 | "prettier",
14 | ],
15 | rules: {
16 | "no-empty": "warn",
17 | "prettier/prettier": 2,
18 | "no-implicit-coercion": ["warn", { allow: ["!!"] }],
19 | curly: ["error", "all"],
20 | "@typescript-eslint/no-explicit-any": "off"
21 | },
22 | env: {
23 | node: true,
24 | "jest/globals": true,
25 | },
26 | }
27 |
--------------------------------------------------------------------------------
/.gitbook.yaml:
--------------------------------------------------------------------------------
1 |
2 | root: ./docs/
3 |
4 | structure:
5 | readme: ../README.md
6 | summary: ./SUMMARY.md
--------------------------------------------------------------------------------
/.github/workflows/npmpublish.yml:
--------------------------------------------------------------------------------
1 | name: npm publish
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | build-binaries:
9 | strategy:
10 | matrix:
11 | os: [windows, macos, ubuntu]
12 | include:
13 | - os: windows
14 | build: npx caxa --directory . --command "{{caxa}}/node_modules/.bin/node" "{{caxa}}/cli.js" --output "everdev-windows.exe"
15 | artifact: "everdev-windows.exe"
16 | - os: macos
17 | build: |
18 | npx caxa --directory . --command "{{caxa}}/node_modules/.bin/node" "{{caxa}}/cli.js" --output "everdev"
19 | tar -czf "everdev-macos.tgz" "everdev"
20 | artifact: everdev-macos.tgz
21 | - os: ubuntu
22 | build: |
23 | npx caxa --directory . --command "{{caxa}}/node_modules/.bin/node" "{{caxa}}/cli.js" --output "everdev"
24 | tar -czf "everdev-linux.tgz" "everdev"
25 | artifact: everdev-linux.tgz
26 | runs-on: ${{ matrix.os }}-latest
27 | steps:
28 | - uses: actions/checkout@v2
29 | - uses: actions/setup-node@v1
30 | with:
31 | node-version: 12
32 | registry-url: https://registry.npmjs.org/
33 | - run: |
34 | npm i
35 | npx tsc
36 | ${{ matrix.build }}
37 | - uses: softprops/action-gh-release@v1
38 | with:
39 | files: ${{ matrix.artifact }}
40 | env:
41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42 |
43 | publish-npm:
44 | needs: [build-binaries]
45 | runs-on: ubuntu-latest
46 | steps:
47 | - uses: actions/checkout@v2
48 | - uses: actions/setup-node@v1
49 | with:
50 | node-version: 12
51 | registry-url: https://registry.npmjs.org/
52 | - run: |
53 | npm publish
54 | env:
55 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
56 |
57 | send-discord-msg:
58 | needs: [publish-npm]
59 | runs-on: ubuntu-latest
60 | steps:
61 | - name: Discord notification
62 | env:
63 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
64 | uses: Ilshidur/action-discord@master
65 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 | .pnpm-debug.log*
9 | .vscode/*
10 |
11 | # Diagnostic reports (https://nodejs.org/api/report.html)
12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
13 |
14 | # Runtime data
15 | pids
16 | *.pid
17 | *.seed
18 | *.pid.lock
19 |
20 | # Directory for instrumented libs generated by jscoverage/JSCover
21 | lib-cov
22 |
23 | # Coverage directory used by tools like istanbul
24 | coverage
25 | *.lcov
26 |
27 | # nyc test coverage
28 | .nyc_output
29 |
30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
31 | .grunt
32 |
33 | # Bower dependency directory (https://bower.io/)
34 | bower_components
35 |
36 | # node-waf configuration
37 | .lock-wscript
38 |
39 | # Compiled binary addons (https://nodejs.org/api/addons.html)
40 | build/Release
41 |
42 | # Dependency directories
43 | node_modules/
44 | jspm_packages/
45 |
46 | # Snowpack dependency directory (https://snowpack.dev/)
47 | web_modules/
48 |
49 | # TypeScript cache
50 | *.tsbuildinfo
51 |
52 | # Optional npm cache directory
53 | .npm
54 |
55 | # Optional eslint cache
56 | .eslintcache
57 |
58 | # Microbundle cache
59 | .rpt2_cache/
60 | .rts2_cache_cjs/
61 | .rts2_cache_es/
62 | .rts2_cache_umd/
63 |
64 | # Optional REPL history
65 | .node_repl_history
66 |
67 | # Output of 'npm pack'
68 | *.tgz
69 |
70 | # Yarn Integrity file
71 | .yarn-integrity
72 |
73 | # dotenv environment variables file
74 | .env
75 | .env.test
76 | .env.production
77 |
78 | # parcel-bundler cache (https://parceljs.org/)
79 | .cache
80 | .parcel-cache
81 |
82 | # Next.js build output
83 | .next
84 | out
85 |
86 | # Nuxt.js build / generate output
87 | .nuxt
88 | dist
89 |
90 | # Gatsby files
91 | .cache/
92 | # Comment in the public line in if your project uses Gatsby and not Next.js
93 | # https://nextjs.org/blog/next-9-1#public-directory-support
94 | # public
95 |
96 | # vuepress build output
97 | .vuepress/dist
98 |
99 | # Serverless directories
100 | .serverless/
101 |
102 | # FuseBox cache
103 | .fusebox/
104 |
105 | # DynamoDB Local files
106 | .dynamodb/
107 |
108 | # TernJS port file
109 | .tern-port
110 |
111 | # Stores VSCode versions used for testing VSCode extensions
112 | .vscode-test
113 |
114 | # yarn v2
115 | .yarn/cache
116 | .yarn/unplugged
117 | .yarn/build-state.yml
118 | .yarn/install-state.gz
119 | .pnp.*
120 | .idea
121 | /package-lock.json
122 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *
2 | !src/**/*
3 | !dist/**/*
4 | dist/**/*.test.*
5 | !contracts/**/*
6 | !package.json
7 | !README.md
8 | **/*.map
9 | src/
10 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "tabWidth": 4,
4 | "semi": false,
5 | "singleQuote": false,
6 | "printWidth": 80,
7 | "arrowParens": "avoid",
8 | "bracketSpacing": true,
9 | "endOfLine": "lf",
10 | "proseWrap": "preserve",
11 | "quoteProps": "as-needed",
12 | "requirePragma": false,
13 | "useTabs": false
14 | }
15 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["dbaeumer.vscode-eslint"]
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll.eslint": "explicit"
4 | },
5 | "eslint.enable": true,
6 | "eslint.validate": ["javascript", "typescript"],
7 | "editor.formatOnSave": true,
8 | "[javascript]": {
9 | "editor.formatOnSave": false
10 | },
11 | "[typescript]": {
12 | "editor.defaultFormatter": "esbenp.prettier-vscode",
13 | "editor.formatOnSave": true,
14 | "editor.formatOnPaste": false
15 | },
16 | "[markdown]": {
17 | "editor.formatOnSave": true
18 | },
19 | "search.exclude": {
20 | "**/node_modules": true,
21 | "**/bower_components": true,
22 | "**/dist": true,
23 | "**/coverage": true
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "type": "npm",
8 | "script": "build",
9 | "group": {
10 | "kind": "build",
11 | "isDefault": true
12 | }
13 | },
14 | {
15 | "type": "npm",
16 | "script": "start",
17 | "problemMatcher": [],
18 | "label": "npm: start",
19 | "detail": "npm run start"
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/assets/everdev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/assets/everdev.png
--------------------------------------------------------------------------------
/ci/Jenkinsfile:
--------------------------------------------------------------------------------
1 | @Library('infrastructure-jenkins-shared-library') _
2 |
3 | G_gitcred = 'TonJenSSH'
4 | G_giturl = null
5 | G_info = [:]
6 |
7 | def gitbook(project_name = null) {
8 | sshagent([G_gitcred]) {
9 | def tmpFolder = UUID.randomUUID().toString()
10 | sh """
11 | git clone -b gitbook git@github.com:everx-labs/${project_name} ${tmpFolder}
12 | """
13 | dir(tmpFolder) {
14 | try {
15 | sh """
16 | git merge origin/main
17 | git push --set-upstream origin gitbook
18 | """
19 | def newPR = gitFunc.createPR(project_name, 'gitbook', 'main', 'Update docs from gitbook')
20 | def num = newPR.number
21 | if (num) {
22 | def sha = gitFunc.infoPR(project_name, num).head.sha
23 | def context = "continuous-integration/jenkins/pr-merge"
24 | gitFunc.setGitHubBuildStatus(project_name, sha, true, 'Updated by Jenkins pipeline', context)
25 | gitFunc.approvePR(project_name, num)
26 | println( gitFunc.mergePR(project_name, num) )
27 | }
28 | } catch(ex) {
29 | echo ex
30 | }
31 | deleteDir()
32 | }
33 | }
34 | }
35 |
36 | def test_jenkins(project_name = null) {
37 | println("test: Jenkins ${project_name}")
38 | }
39 |
40 | pipeline {
41 | agent {
42 | label 'master'
43 | }
44 | stages{
45 | stage('Prepare data') {
46 | steps {
47 | script {
48 | def jNameParts = env.JOB_NAME.split('/')
49 |
50 | // get triggered project
51 | G_info.put('project', jNameParts[jNameParts.size()-2])
52 |
53 | // set url
54 | G_giturl = env.GIT_URL
55 | if(!G_giturl) {
56 | error "It seems like GIT_URL (${env.GIT_URL}) variable wasn't set.\n" +
57 | "Make sure that your branch (or PR) has no merge conflicts, otherwise resolve them and try again."
58 | }
59 |
60 | // get triggered branch
61 | G_info.put('branch', "${env.BRANCH_NAME}")
62 |
63 | // // get project settings
64 | // try {
65 | // G_projects_config = json.json2map(["text": gitFunc.getSingleFile('ton-builder', 'master', 'project_settings.json').toString()]).findAll{proj, data ->
66 | // proj == G_info.project.toLowerCase().trim()
67 | // }.collect{proj, data -> data}[0]
68 | // G_dev_processing = G_projects_config.dev_processing.toString() != 'null'
69 | // } catch(ex) {
70 | // echo "Can't get project data"
71 | // }
72 |
73 | // branch is PR
74 | G_info.put('isPR', G_info.branch ==~ /^PR-\d+/ ? true : false)
75 |
76 | // check reason
77 | if(G_info.branch == "main") {
78 | // def commitText = sh(script: 'git log -1 --pretty=%B', returnStdout: true).trim().split('\n').findAll{rec ->
79 | // rec.trim() != '' && !(rec ==~ /.*Merge.*/)
80 | // }
81 | // if(commitText.size() == 0) {
82 | // commitText = sh(script: 'git log -2 --pretty=%B', returnStdout: true).trim().split('\n').findAll{rec ->
83 | // rec.trim() != '' && !(rec ==~ /.*Merge.*/)
84 | // }
85 | // }
86 | // commitText = commitText.join('\n')
87 | // echo "${commitText}"
88 | // if(
89 | // commitText.indexOf("Update patch version because of dependencies changes") >= 0 ||
90 | // commitText.indexOf("Automatic project update") >= 0
91 | // ) {
92 | // G_process_build = false
93 | // }
94 | } else if (G_info.branch == 'gitbook') {
95 | println("resolution: gitbook")
96 | gitbook('everdev')
97 | //currentBuild.result = 'SUCCESS'
98 | //build job: "Builder/gitbook"
99 | //return
100 | } else if (G_info.branch == 'jenkins') {
101 | println("test: Jenkins")
102 | test_jenkins('everdev')
103 | //currentBuild.result = 'SUCCESS'
104 | //build job: "Everdev/ci/jenkins"
105 | //return
106 | }
107 | }
108 | }
109 | }
110 | }
111 | post {
112 | always {
113 | cleanWs()
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/ci/gitbook/Jenkinsfile:
--------------------------------------------------------------------------------
1 | @Library('infrastructure-jenkins-shared-library') _
2 |
3 | G_gitcred = 'TonJenSSH'
4 |
5 | pipeline {
6 | agent {
7 | label 'master'
8 | }
9 | stages{
10 | stage('Publish gitbook branch into main') {
11 | steps {
12 | script {
13 | sshagent([G_gitcred]) {
14 | def tmpFolder = UUID.randomUUID().toString()
15 | sh """
16 | git clone -b gitbook git@github.com:everx-labs/everdev ${tmpFolder}
17 | """
18 | dir(tmpFolder) {
19 | try {
20 | sh """
21 | git merge origin/main
22 | git push --set-upstream origin gitbook
23 | """
24 | def newPR = gitFunc.createPR('everdev', 'gitbook', 'main', 'Update docs from gitbook')
25 | def num = newPR.number
26 | if (num) {
27 | def sha = gitFunc.infoPR('everdev', num).head.sha
28 | def context = "continuous-integration/jenkins/pr-merge"
29 | gitFunc.setGitHubBuildStatus('everdev', sha, true, 'Updated by Jenkins pipeline', context)
30 | gitFunc.approvePR('everdev', num)
31 | println( gitFunc.mergePR('everdev', num) )
32 | }
33 | } catch(ex) {
34 | echo ex
35 | }
36 | deleteDir()
37 | }
38 | }
39 | }
40 | }
41 | }
42 | }
43 | post {
44 | always {
45 | cleanWs()
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/ci/jenkins/Jenkinsfile:
--------------------------------------------------------------------------------
1 | @Library('infrastructure-jenkins-shared-library') _
2 |
3 | G_gitcred = 'TonJenSSH'
4 |
5 | pipeline {
6 | agent {
7 | label 'master'
8 | }
9 | stages{
10 | stage('test: Jenkins') {
11 | steps {
12 | script {
13 | println("test: Jenkins")
14 | }
15 | }
16 | }
17 | }
18 | post {
19 | always {
20 | cleanWs()
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const { consoleTerminal, everdevInit, everdevDone, cli } = require("./dist")
4 | const { rewriteKnownErrors } = require("./dist/rewriteKnownErrors")
5 |
6 | ;(async () => {
7 | try {
8 | everdevInit()
9 | await cli.run(consoleTerminal)
10 | everdevDone()
11 | } catch (err) {
12 | if (!(err instanceof Error)) {
13 | const { data, code } = err
14 | err = new Error(err.message)
15 | err.code = code
16 | err.data = data
17 | }
18 | err = rewriteKnownErrors(err)
19 | console.error(`${err}`)
20 | process.exit(1)
21 | }
22 | })()
23 |
--------------------------------------------------------------------------------
/contracts/GiverV1.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 1,
3 | "functions": [
4 | {
5 | "name": "constructor",
6 | "inputs": [],
7 | "outputs": []
8 | },
9 | {
10 | "name": "sendGrams",
11 | "inputs": [
12 | { "name": "dest", "type": "address" },
13 | { "name": "amount", "type": "uint64" }
14 | ],
15 | "outputs": []
16 | }
17 | ],
18 | "events": [],
19 | "data": []
20 | }
21 |
--------------------------------------------------------------------------------
/contracts/GiverV2.abi.json:
--------------------------------------------------------------------------------
1 | {"ABI version": 2,
2 | "header": ["time", "expire"],
3 | "functions": [
4 | {
5 | "name": "upgrade",
6 | "inputs": [
7 | {"name":"newcode","type":"cell"}
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "sendTransaction",
14 | "inputs": [
15 | {"name":"dest","type":"address"},
16 | {"name":"value","type":"uint128"},
17 | {"name":"bounce","type":"bool"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "getMessages",
24 | "inputs": [
25 | ],
26 | "outputs": [
27 | {"components":[{"name":"hash","type":"uint256"},{"name":"expireAt","type":"uint64"}],"name":"messages","type":"tuple[]"}
28 | ]
29 | },
30 | {
31 | "name": "constructor",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | ]
36 | }
37 | ],
38 | "events": [
39 | ]
40 | }
--------------------------------------------------------------------------------
/contracts/GiverV2.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/contracts/GiverV2.tvc
--------------------------------------------------------------------------------
/contracts/GiverV3.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "version": "2.3",
4 | "header": ["time", "expire"],
5 | "functions": [
6 | {
7 | "name": "sendTransaction",
8 | "inputs": [
9 | {"name":"dest","type":"address"},
10 | {"name":"value","type":"uint128"},
11 | {"name":"bounce","type":"bool"}
12 | ],
13 | "outputs": [
14 | ]
15 | },
16 | {
17 | "name": "getMessages",
18 | "inputs": [
19 | ],
20 | "outputs": [
21 | {"components":[{"name":"hash","type":"uint256"},{"name":"expireAt","type":"uint32"}],"name":"messages","type":"tuple[]"}
22 | ]
23 | },
24 | {
25 | "name": "upgrade",
26 | "inputs": [
27 | {"name":"newcode","type":"cell"}
28 | ],
29 | "outputs": [
30 | ]
31 | },
32 | {
33 | "name": "constructor",
34 | "inputs": [
35 | ],
36 | "outputs": [
37 | ]
38 | }
39 | ],
40 | "data": [
41 | ],
42 | "events": [
43 | ],
44 | "fields": [
45 | {"name":"_pubkey","type":"uint256"},
46 | {"name":"_constructorFlag","type":"bool"},
47 | {"name":"m_messages","type":"map(uint256,uint32)"}
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------
/contracts/GiverV3.sol:
--------------------------------------------------------------------------------
1 | pragma ever-solidity >= 0.61.2;
2 | pragma AbiHeader time;
3 | pragma AbiHeader expire;
4 |
5 | abstract contract Upgradable {
6 | /*
7 | * Set code
8 | */
9 |
10 | function upgrade(TvmCell newcode) public virtual {
11 | require(msg.pubkey() == tvm.pubkey(), 101);
12 | tvm.accept();
13 | tvm.commit();
14 | tvm.setcode(newcode);
15 | tvm.setCurrentCode(newcode);
16 | onCodeUpgrade();
17 | }
18 |
19 | function onCodeUpgrade() internal virtual;
20 | }
21 |
22 | contract GiverV3 is Upgradable {
23 |
24 | uint8 constant MAX_CLEANUP_MSGS = 30;
25 | mapping(uint256 => uint32) m_messages;
26 |
27 | modifier acceptOnlyOwner {
28 | require(msg.pubkey() == tvm.pubkey(), 101);
29 | tvm.accept();
30 | _;
31 | }
32 |
33 | /*
34 | * Publics
35 | */
36 |
37 | /// @notice Allows to accept simple transfers.
38 | receive() external {}
39 |
40 | /// @notice Transfers grams to other contracts.
41 | function sendTransaction(address dest, uint128 value, bool bounce) public {
42 | dest.transfer(value, bounce, 3);
43 | gc();
44 | }
45 |
46 | /*
47 | * Privates
48 | */
49 |
50 | /// @notice Function with predefined name called after signature check. Used to
51 | /// implement custom replay protection with parallel access.
52 | function afterSignatureCheck(TvmSlice body, TvmCell) private inline
53 | returns (TvmSlice)
54 | {
55 | // owner check
56 | require(msg.pubkey() == tvm.pubkey(), 101);
57 | uint256 bodyHash = tvm.hash(body);
58 | // load and drop message timestamp (uint64)
59 | (, uint32 expireAt) = body.decode(uint64, uint32);
60 | require(expireAt > now, 57);
61 | require(!m_messages.exists(bodyHash), 102);
62 |
63 | tvm.accept();
64 | m_messages[bodyHash] = expireAt;
65 |
66 | return body;
67 | }
68 |
69 | /// @notice Allows to delete expired messages from dict.
70 | function gc() private inline {
71 | uint counter = 0;
72 | for ((uint256 bodyHash, uint32 expireAt) : m_messages) {
73 | if (counter >= MAX_CLEANUP_MSGS) {
74 | break;
75 | }
76 | counter++;
77 | if (expireAt <= now) {
78 | delete m_messages[bodyHash];
79 | }
80 | }
81 | }
82 |
83 | /*
84 | * Get methods
85 | */
86 | struct Message {
87 | uint256 hash;
88 | uint32 expireAt;
89 | }
90 | function getMessages() public view returns (Message[] messages) {
91 | for ((uint256 msgHash, uint32 expireAt) : m_messages) {
92 | messages.push(Message(msgHash, expireAt));
93 | }
94 | }
95 |
96 | function onCodeUpgrade() internal override {}
97 | }
98 |
--------------------------------------------------------------------------------
/contracts/GiverV3.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/contracts/GiverV3.tvc
--------------------------------------------------------------------------------
/contracts/HelloWallet.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "version": "2.2",
4 | "header": ["time", "expire"],
5 | "functions": [
6 | {
7 | "name": "constructor",
8 | "inputs": [
9 | ],
10 | "outputs": [
11 | ]
12 | },
13 | {
14 | "name": "renderHelloWorld",
15 | "inputs": [
16 | ],
17 | "outputs": [
18 | {"name":"value0","type":"string"}
19 | ]
20 | },
21 | {
22 | "name": "touch",
23 | "inputs": [
24 | ],
25 | "outputs": [
26 | ]
27 | },
28 | {
29 | "name": "getTimestamp",
30 | "inputs": [
31 | ],
32 | "outputs": [
33 | {"name":"value0","type":"uint256"}
34 | ]
35 | },
36 | {
37 | "name": "sendValue",
38 | "inputs": [
39 | {"name":"dest","type":"address"},
40 | {"name":"amount","type":"uint128"},
41 | {"name":"bounce","type":"bool"}
42 | ],
43 | "outputs": [
44 | ]
45 | },
46 | {
47 | "name": "timestamp",
48 | "inputs": [
49 | ],
50 | "outputs": [
51 | {"name":"timestamp","type":"uint32"}
52 | ]
53 | }
54 | ],
55 | "data": [
56 | ],
57 | "events": [
58 | ],
59 | "fields": [
60 | {"name":"_pubkey","type":"uint256"},
61 | {"name":"_timestamp","type":"uint64"},
62 | {"name":"_constructorFlag","type":"bool"},
63 | {"name":"timestamp","type":"uint32"}
64 | ]
65 | }
66 |
--------------------------------------------------------------------------------
/contracts/HelloWallet.sol:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * This file was generated by EverDev.
4 | * EverDev is a part of EVER OS (see http://ton.dev).
5 | */
6 | pragma ton-solidity >= 0.67.0;
7 | pragma AbiHeader expire;
8 |
9 | // This is class that describes you smart contract.
10 | contract HelloWallet {
11 | // Contract can have an instance variables.
12 | // In this example instance variable `timestamp` is used to store the time of `constructor` or `touch`
13 | // function call
14 | uint32 public timestamp;
15 |
16 | // Contract can have a `constructor` – function that will be called when contract will be deployed to the blockchain.
17 | // In this example constructor adds current time to the instance variable.
18 | // All contracts need call tvm.accept(); for succeeded deploy
19 | constructor() {
20 | // Check that contract's public key is set
21 | require(tvm.pubkey() != 0, 101);
22 | // Check that message has signature (msg.pubkey() is not zero) and
23 | // message is signed with the owner's private key
24 | require(msg.pubkey() == tvm.pubkey(), 102);
25 | // The current smart contract agrees to buy some gas to finish the
26 | // current transaction. This actions required to process external
27 | // messages, which bring no value (henceno gas) with themselves.
28 | tvm.accept();
29 |
30 | timestamp = block.timestamp;
31 | }
32 |
33 | function renderHelloWorld () public pure returns (string) {
34 | tvm.accept();
35 | return 'helloWorld';
36 | }
37 |
38 | // Updates variable `timestamp` with current blockchain time.
39 | function touch() external {
40 | // Skip signature check
41 | // require(msg.pubkey() == tvm.pubkey(), 102);
42 |
43 | // Tells to the TVM that we accept this message.
44 | tvm.accept();
45 | // Update timestamp
46 | timestamp = block.timestamp;
47 | }
48 |
49 | // Function returns value of state variable `timestamp`
50 | function getTimestamp() public view returns (uint) {
51 | tvm.accept();
52 | return timestamp;
53 | }
54 |
55 | // Send specified amount of tokens to the specified address
56 | function sendValue(address dest, coins amount, bool bounce) public view {
57 | require(msg.pubkey() == tvm.pubkey(), 102);
58 | tvm.accept();
59 | // It allows to make a transfer with arbitrary settings
60 | dest.transfer(amount, bounce, 0);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/contracts/HelloWallet.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/contracts/HelloWallet.tvc
--------------------------------------------------------------------------------
/contracts/MsigV2.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "version": "2.3",
4 | "header": ["pubkey", "time", "expire"],
5 | "functions": [
6 | {
7 | "name": "constructor",
8 | "inputs": [
9 | {"name":"owners","type":"uint256[]"},
10 | {"name":"reqConfirms","type":"uint8"},
11 | {"name":"lifetime","type":"uint32"}
12 | ],
13 | "outputs": [
14 | ]
15 | },
16 | {
17 | "name": "sendTransaction",
18 | "inputs": [
19 | {"name":"dest","type":"address"},
20 | {"name":"value","type":"uint128"},
21 | {"name":"bounce","type":"bool"},
22 | {"name":"flags","type":"uint8"},
23 | {"name":"payload","type":"cell"}
24 | ],
25 | "outputs": [
26 | ]
27 | },
28 | {
29 | "name": "submitTransaction",
30 | "inputs": [
31 | {"name":"dest","type":"address"},
32 | {"name":"value","type":"uint128"},
33 | {"name":"bounce","type":"bool"},
34 | {"name":"allBalance","type":"bool"},
35 | {"name":"payload","type":"cell"},
36 | {"name":"stateInit","type":"optional(cell)"}
37 | ],
38 | "outputs": [
39 | {"name":"transId","type":"uint64"}
40 | ]
41 | },
42 | {
43 | "name": "confirmTransaction",
44 | "inputs": [
45 | {"name":"transactionId","type":"uint64"}
46 | ],
47 | "outputs": [
48 | ]
49 | },
50 | {
51 | "name": "isConfirmed",
52 | "inputs": [
53 | {"name":"mask","type":"uint32"},
54 | {"name":"index","type":"uint8"}
55 | ],
56 | "outputs": [
57 | {"name":"confirmed","type":"bool"}
58 | ]
59 | },
60 | {
61 | "name": "getParameters",
62 | "inputs": [
63 | ],
64 | "outputs": [
65 | {"name":"maxQueuedTransactions","type":"uint8"},
66 | {"name":"maxCustodianCount","type":"uint8"},
67 | {"name":"expirationTime","type":"uint64"},
68 | {"name":"minValue","type":"uint128"},
69 | {"name":"requiredTxnConfirms","type":"uint8"},
70 | {"name":"requiredUpdConfirms","type":"uint8"}
71 | ]
72 | },
73 | {
74 | "name": "getTransaction",
75 | "inputs": [
76 | {"name":"transactionId","type":"uint64"}
77 | ],
78 | "outputs": [
79 | {"components":[{"name":"id","type":"uint64"},{"name":"confirmationsMask","type":"uint32"},{"name":"signsRequired","type":"uint8"},{"name":"signsReceived","type":"uint8"},{"name":"creator","type":"uint256"},{"name":"index","type":"uint8"},{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"sendFlags","type":"uint16"},{"name":"payload","type":"cell"},{"name":"bounce","type":"bool"},{"name":"stateInit","type":"optional(cell)"}],"name":"trans","type":"tuple"}
80 | ]
81 | },
82 | {
83 | "name": "getTransactions",
84 | "inputs": [
85 | ],
86 | "outputs": [
87 | {"components":[{"name":"id","type":"uint64"},{"name":"confirmationsMask","type":"uint32"},{"name":"signsRequired","type":"uint8"},{"name":"signsReceived","type":"uint8"},{"name":"creator","type":"uint256"},{"name":"index","type":"uint8"},{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"sendFlags","type":"uint16"},{"name":"payload","type":"cell"},{"name":"bounce","type":"bool"},{"name":"stateInit","type":"optional(cell)"}],"name":"transactions","type":"tuple[]"}
88 | ]
89 | },
90 | {
91 | "name": "getCustodians",
92 | "inputs": [
93 | ],
94 | "outputs": [
95 | {"components":[{"name":"index","type":"uint8"},{"name":"pubkey","type":"uint256"}],"name":"custodians","type":"tuple[]"}
96 | ]
97 | },
98 | {
99 | "name": "submitUpdate",
100 | "inputs": [
101 | {"name":"codeHash","type":"optional(uint256)"},
102 | {"name":"owners","type":"optional(uint256[])"},
103 | {"name":"reqConfirms","type":"optional(uint8)"},
104 | {"name":"lifetime","type":"optional(uint32)"}
105 | ],
106 | "outputs": [
107 | {"name":"updateId","type":"uint64"}
108 | ]
109 | },
110 | {
111 | "name": "confirmUpdate",
112 | "inputs": [
113 | {"name":"updateId","type":"uint64"}
114 | ],
115 | "outputs": [
116 | ]
117 | },
118 | {
119 | "name": "executeUpdate",
120 | "inputs": [
121 | {"name":"updateId","type":"uint64"},
122 | {"name":"code","type":"optional(cell)"}
123 | ],
124 | "outputs": [
125 | ]
126 | },
127 | {
128 | "name": "getUpdateRequests",
129 | "inputs": [
130 | ],
131 | "outputs": [
132 | {"components":[{"name":"id","type":"uint64"},{"name":"index","type":"uint8"},{"name":"signs","type":"uint8"},{"name":"confirmationsMask","type":"uint32"},{"name":"creator","type":"uint256"},{"name":"codeHash","type":"optional(uint256)"},{"name":"custodians","type":"optional(uint256[])"},{"name":"reqConfirms","type":"optional(uint8)"},{"name":"lifetime","type":"optional(uint32)"}],"name":"updates","type":"tuple[]"}
133 | ]
134 | }
135 | ],
136 | "data": [
137 | ],
138 | "events": [
139 | ],
140 | "fields": [
141 | {"name":"_pubkey","type":"uint256"},
142 | {"name":"_timestamp","type":"uint64"},
143 | {"name":"_constructorFlag","type":"bool"},
144 | {"name":"m_ownerKey","type":"uint256"},
145 | {"name":"m_requestsMask","type":"uint256"},
146 | {"components":[{"name":"id","type":"uint64"},{"name":"confirmationsMask","type":"uint32"},{"name":"signsRequired","type":"uint8"},{"name":"signsReceived","type":"uint8"},{"name":"creator","type":"uint256"},{"name":"index","type":"uint8"},{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"sendFlags","type":"uint16"},{"name":"payload","type":"cell"},{"name":"bounce","type":"bool"},{"name":"stateInit","type":"optional(cell)"}],"name":"m_transactions","type":"map(uint64,tuple)"},
147 | {"name":"m_custodians","type":"map(uint256,uint8)"},
148 | {"name":"m_custodianCount","type":"uint8"},
149 | {"components":[{"name":"id","type":"uint64"},{"name":"index","type":"uint8"},{"name":"signs","type":"uint8"},{"name":"confirmationsMask","type":"uint32"},{"name":"creator","type":"uint256"},{"name":"codeHash","type":"optional(uint256)"},{"name":"custodians","type":"optional(uint256[])"},{"name":"reqConfirms","type":"optional(uint8)"},{"name":"lifetime","type":"optional(uint32)"}],"name":"m_updateRequests","type":"map(uint64,tuple)"},
150 | {"name":"m_updateRequestsMask","type":"uint32"},
151 | {"name":"m_requiredVotes","type":"uint8"},
152 | {"name":"m_defaultRequiredConfirmations","type":"uint8"},
153 | {"name":"m_lifetime","type":"uint32"}
154 | ]
155 | }
156 |
--------------------------------------------------------------------------------
/contracts/MsigV2.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/contracts/MsigV2.tvc
--------------------------------------------------------------------------------
/contracts/SafeMultisigWallet.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"owners","type":"uint256[]"},
9 | {"name":"reqConfirms","type":"uint8"}
10 | ],
11 | "outputs": [
12 | ]
13 | },
14 | {
15 | "name": "acceptTransfer",
16 | "inputs": [
17 | {"name":"payload","type":"bytes"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "sendTransaction",
24 | "inputs": [
25 | {"name":"dest","type":"address"},
26 | {"name":"value","type":"uint128"},
27 | {"name":"bounce","type":"bool"},
28 | {"name":"flags","type":"uint8"},
29 | {"name":"payload","type":"cell"}
30 | ],
31 | "outputs": [
32 | ]
33 | },
34 | {
35 | "name": "submitTransaction",
36 | "inputs": [
37 | {"name":"dest","type":"address"},
38 | {"name":"value","type":"uint128"},
39 | {"name":"bounce","type":"bool"},
40 | {"name":"allBalance","type":"bool"},
41 | {"name":"payload","type":"cell"}
42 | ],
43 | "outputs": [
44 | {"name":"transId","type":"uint64"}
45 | ]
46 | },
47 | {
48 | "name": "confirmTransaction",
49 | "inputs": [
50 | {"name":"transactionId","type":"uint64"}
51 | ],
52 | "outputs": [
53 | ]
54 | },
55 | {
56 | "name": "isConfirmed",
57 | "inputs": [
58 | {"name":"mask","type":"uint32"},
59 | {"name":"index","type":"uint8"}
60 | ],
61 | "outputs": [
62 | {"name":"confirmed","type":"bool"}
63 | ]
64 | },
65 | {
66 | "name": "getParameters",
67 | "inputs": [
68 | ],
69 | "outputs": [
70 | {"name":"maxQueuedTransactions","type":"uint8"},
71 | {"name":"maxCustodianCount","type":"uint8"},
72 | {"name":"expirationTime","type":"uint64"},
73 | {"name":"minValue","type":"uint128"},
74 | {"name":"requiredTxnConfirms","type":"uint8"}
75 | ]
76 | },
77 | {
78 | "name": "getTransaction",
79 | "inputs": [
80 | {"name":"transactionId","type":"uint64"}
81 | ],
82 | "outputs": [
83 | {"components":[{"name":"id","type":"uint64"},{"name":"confirmationsMask","type":"uint32"},{"name":"signsRequired","type":"uint8"},{"name":"signsReceived","type":"uint8"},{"name":"creator","type":"uint256"},{"name":"index","type":"uint8"},{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"sendFlags","type":"uint16"},{"name":"payload","type":"cell"},{"name":"bounce","type":"bool"}],"name":"trans","type":"tuple"}
84 | ]
85 | },
86 | {
87 | "name": "getTransactions",
88 | "inputs": [
89 | ],
90 | "outputs": [
91 | {"components":[{"name":"id","type":"uint64"},{"name":"confirmationsMask","type":"uint32"},{"name":"signsRequired","type":"uint8"},{"name":"signsReceived","type":"uint8"},{"name":"creator","type":"uint256"},{"name":"index","type":"uint8"},{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"sendFlags","type":"uint16"},{"name":"payload","type":"cell"},{"name":"bounce","type":"bool"}],"name":"transactions","type":"tuple[]"}
92 | ]
93 | },
94 | {
95 | "name": "getTransactionIds",
96 | "inputs": [
97 | ],
98 | "outputs": [
99 | {"name":"ids","type":"uint64[]"}
100 | ]
101 | },
102 | {
103 | "name": "getCustodians",
104 | "inputs": [
105 | ],
106 | "outputs": [
107 | {"components":[{"name":"index","type":"uint8"},{"name":"pubkey","type":"uint256"}],"name":"custodians","type":"tuple[]"}
108 | ]
109 | }
110 | ],
111 | "data": [
112 | ],
113 | "events": [
114 | {
115 | "name": "TransferAccepted",
116 | "inputs": [
117 | {"name":"payload","type":"bytes"}
118 | ],
119 | "outputs": [
120 | ]
121 | }
122 | ]
123 | }
124 |
--------------------------------------------------------------------------------
/contracts/SafeMultisigWallet.keys.json:
--------------------------------------------------------------------------------
1 | {
2 | "public": "99c84f920c299b5d80e4fcce2d2054b05466ec9df19532a688c10eb6dd8d6b33",
3 | "secret": "73b60dc6a5b1d30a56a81ea85e0e453f6957dbfbeefb57325ca9f7be96d3fe1a"
4 | }
--------------------------------------------------------------------------------
/contracts/SafeMultisigWallet.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/contracts/SafeMultisigWallet.tvc
--------------------------------------------------------------------------------
/contracts/seGiver.keys.json:
--------------------------------------------------------------------------------
1 | {
2 | "public": "2ada2e65ab8eeab09490e3521415f45b6e42df9c760a639bcf53957550b25a16",
3 | "secret": "172af540e43a524763dd53b26a066d472a97c4de37d5498170564510608250c3"
4 | }
--------------------------------------------------------------------------------
/docs/.gitbook/assets/Everscale Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/docs/.gitbook/assets/Everscale Logo.png
--------------------------------------------------------------------------------
/docs/.gitbook/assets/Everscale Logo.svg:
--------------------------------------------------------------------------------
1 |
20 |
--------------------------------------------------------------------------------
/docs/.gitbook/assets/vf-dev-program.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/everx-labs/everdev/af680664adeea4fc536fefab298ab4eb1d4503eb/docs/.gitbook/assets/vf-dev-program.png
--------------------------------------------------------------------------------
/docs/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Table of contents
2 |
3 | * [EverDev](../README.md)
4 | * [Troubleshooting](troubleshooting.md)
5 | * [Use in JS applications](use-in-js-applications.md)
6 |
7 | ## Command line interface
8 |
9 | * [Solidity](command-line-interface/solidity.md)
10 | * [Solidity Compiler Driver](command-line-interface/solidity-compiler-driver.md)
11 | * [C++](command-line-interface/c.md)
12 | * [Evernode SE](command-line-interface/evernode-platform-startup-edition-se.md)
13 | * [Network Tool](command-line-interface/network-tool.md)
14 | * [Signer Tool](command-line-interface/signer-tool.md)
15 | * [Contract management](command-line-interface/contract-management.md)
16 | * [TestSuite4](command-line-interface/testsuite4.md)
17 | * [DeBrowser](command-line-interface/debrowser.md)
18 |
19 | ## Guides
20 |
21 | * [Quick Start](guides/quick-start.md)
22 | * [Create controller](guides/creating-controller.md)
23 | * [View controller info](view-controller-info.md)
24 |
25 | ## Links
26 |
27 | * [everdev repository](https://github.com/everx-labs/everdev)
28 | * [ever-sdk repository](https://github.com/everx-labs/ever-sdk)
29 |
--------------------------------------------------------------------------------
/docs/command-line-interface/c.md:
--------------------------------------------------------------------------------
1 | # C++
2 |
3 | ## Create your first contract
4 |
5 | This command creates a basic C++ contract with comments that you can observe and compile.
6 |
7 | ```shell
8 | everdev clang create Contract
9 | ```
10 |
11 | ## Compile
12 |
13 | This command compiles and links a selected C++ contract. After successful compilation you get .abi.json and .tvc files that you can later [use in your DApps to deploy and run contract methods](https://docs.everos.dev/ever-sdk/guides/work\_with\_contracts/add\_contract\_to\_your\_app).
14 |
15 | ```shell
16 | everdev clang compile Contract.cpp
17 | ```
18 |
19 | ## Version
20 |
21 | This command shows the currently installed C++ compiler version.
22 |
23 | ```shell
24 | everdev clang version
25 | ```
26 |
27 | ## Update
28 |
29 | This command updates the compiler to the latest version.
30 |
31 | ```shell
32 | everdev clang update
33 | ```
34 |
35 | Use `--force` or `-f` option to force reinstall, if the compiler is already up to date.
36 |
37 | ## Set
38 |
39 | This command sets the compiler version and downloads it if needed.
40 |
41 | ```shell
42 | everdev clang set --compiler 7.0.0
43 | ```
44 |
45 | Use `--force` or `-f` option to force reinstall, if the current version is the same as the requested version.
46 |
--------------------------------------------------------------------------------
/docs/command-line-interface/debrowser.md:
--------------------------------------------------------------------------------
1 | # DeBrowser
2 | [The ExtraTON DeBot Browser](https://github.com/extraton/debrowser/).
3 |
4 | ## Version
5 | This command shows the list of available versions.
6 |
7 | ```shell
8 | everdev debrowser version
9 |
10 | Available Versions: 1.1.0, 1.2.0, 1.2.1, 1.3.1
11 | ```
12 |
13 | ## Interfaces
14 | This command shows the list of implemented interfaces.
15 |
16 | ```shell
17 | everdev debrowser interfaces
18 |
19 | Realised interfaces:
20 | - Address Input
21 | - Amount Input
22 | - Confirm Input
23 | - Menu
24 | - Network
25 | - Number Input
26 | - QR Code
27 | - Signing Box Input
28 | - Terminal
29 | - User Info
30 | ```
31 |
32 | ## Start
33 | This command downloads image and starts DeBrowser container (Docker must be launched).
34 |
35 | ```shell
36 | everdev debrowser start 1.3.1
37 | ```
38 |
39 | ## Stop
40 | This command stops DeBrowser container.
41 |
42 | ```shell
43 | everdev debrowser stop
44 | ```
45 |
--------------------------------------------------------------------------------
/docs/command-line-interface/evernode-platform-startup-edition-se.md:
--------------------------------------------------------------------------------
1 | # Evernode SE
2 |
3 | ## Start
4 |
5 | This command starts the Evernode SE container (Docker must be launched). When executed for the first time downloads the latest SE image from dockerhub.
6 |
7 | ```shell
8 | everdev se start
9 | ```
10 |
11 | To make sure ArangoDB starts, [set the ArangoDB port](evernode-platform-startup-edition-se.md#set).
12 |
13 | ## Version
14 |
15 | This command shows the default Evernode SE version and list of other available versions.
16 |
17 | ```shell
18 | everdev se version
19 |
20 | default: 0.24.12
21 | Available Versions: 0, 0.24, 0.24.5, 0.24.6, 0.24.8, 0.24.9, 0.24.10, 0.24.11, 0.24.12, latest
22 | ```
23 |
24 | ## Set
25 |
26 | This command switches Evernode SE to the specified version and port and downloads it, if it is missing. **Attention! This command does not start EVER OS SE, you need to run `start` command separately.**
27 |
28 | ```shell
29 | everdev se set --version 0.24.11 --port 2020
30 | ```
31 |
32 | To make sure ArangoDB starts, use `--db-port` option to set the ArangoDB port:
33 |
34 | ```shell
35 | everdev se set --db-port 8081
36 | ```
37 |
38 | ## Reset
39 |
40 | This command resets the Evernode SE container (Docker must be launched) - restarts it from scratch with a clean database.
41 |
42 | ```shell
43 | everdev se reset
44 | ```
45 |
46 | ## Update
47 |
48 | This command downloads the latest Evernode SE image (Docker must be launched) and starts it.
49 |
50 | ```shell
51 | everdev se update
52 | ```
53 |
54 | ## Stop
55 |
56 | This command stops Evernode SE container.
57 |
58 | ```shell
59 | everdev se stop
60 | ```
61 |
62 | ## Info
63 |
64 | This command shows info about the downloaded versions.
65 |
66 | ```shell
67 | everdev se info
68 |
69 | Instance State Version GraphQL Port ArangoDB Port Docker Container Docker Image
70 | -------- ------- ------- ------------ ------------- -------------------------- --------------------------
71 | default running 0.24.12 2020 tonlabs-tonos-se-ekaterina tonlabs/local-node:0.24.12
72 | ```
73 |
74 | ## Troubleshooting
75 |
76 | View solutions to some frequently encountered problems with Evernode SE [here](../troubleshooting.md).
77 |
--------------------------------------------------------------------------------
/docs/command-line-interface/network-tool.md:
--------------------------------------------------------------------------------
1 | # Network Tool
2 |
3 | Network tool is a convenient way to organize all of your network configurations in one place.
4 |
5 | You can register several blockchains (networks) under short names and then use these names as a target blockchain when working with contracts.
6 |
7 | You can mark one of the networks as a default. It can be used in network commands without providing net name.
8 |
9 | ## Available commands
10 |
11 | See available commands with help command:
12 |
13 | ```
14 | $ everdev network --help
15 | EverDev Version: 1.4.0
16 | Use: everdev network command args [options]
17 | Options:
18 | --help, -h Show command usage
19 | Commands:
20 | add Add net
21 | credentials, c Set credentials for network authentication
22 | delete Delete network from registry
23 | list, l Prints list of networks
24 | info, i Prints network detailed information
25 | default, d Set default network
26 | giver, g Set giver for network
27 | ```
28 |
29 | ## Add a network
30 |
31 | This command adds a network to the everdev registry.
32 |
33 | ```bash
34 | everdev network add network_name network_endpoint(s)
35 | ```
36 |
37 | See other available network addition options with help command:
38 |
39 | ```bash
40 | $ everdev network add -h
41 | EverDev Version: 0.5.0
42 | Use: everdev network add name endpoints [options]
43 | Args:
44 | name
45 | endpoints Comma separated endpoints
46 | Options:
47 | --help, -h Show command usage
48 | --force, -f Overwrite key if already exists
49 | ```
50 |
51 | Example with [mainnet endpoint](https://docs.everos.dev/ever-sdk/reference/ever-os-api/networks):
52 |
53 | ```bash
54 | everdev network add main mainnet.evercloud.dev
55 | ```
56 |
57 | ## Set credentials for a network
58 |
59 | ```
60 | $ everdev network credentials --help
61 | EverDev Version: 1.4.0
62 | Use: everdev network credentials name [options]
63 | Args:
64 | name Network name
65 | Options:
66 | --help, -h Show command usage
67 | --project, -p Your project ID
68 | --access-key, -k Your secret or JWT token
69 | --clear Clear saved credentials (mutually exclusive with other options)
70 | ```
71 |
72 | Access to the devnet and mainnet blockchains requires authorization.\
73 | Create a project on [dashboard.evercloud.dev](https://dashboard.evercloud.dev) if you don't have one, find your "Project Id" and "Secret" (optional) on the "Security" tab, and pass them as parameters:
74 |
75 | Example with "devnet" endpoint:
76 |
77 | ```bash
78 | everdev network credentials devnet --project --access-key
79 | ```
80 |
81 | ## Set a giver for a network
82 |
83 | This command sets a giver account for a network. Giver will be used to top up your account balances on the network, including during deployment.
84 |
85 | ```bash
86 | everdev network giver network_name giver_address --type giver_type
87 | ```
88 |
89 | See other available network addition options with help command:
90 |
91 | ```bash
92 | $ everdev network giver -h
93 | EverDev Version: 0.5.0
94 | Use: everdev network giver name address [options]
95 | Args:
96 | name Network name
97 | address Giver address
98 | Options:
99 | --help, -h Show command usage
100 | --signer, -s Signer to be used with giver
101 | --value, -v Deploying account initial balance in nanotokens
102 | --type, -t Type giver contract (GiverV1 | GiverV2 | GiverV3 | SafeMultisigWallet | MsigV2 | SetcodeMultisigWallet)
103 | ```
104 |
105 | **Note:** The default signer and the initial balance value of 10 tokens will be used, unless otherwise specified through options. Also note, that some contracts may require a higher initial balance for successful deployment. DePool contract, for instance, requires a minimun of 21 tokens.
106 |
107 | Only one giver can be set for a network. Setting another one will overwrite the current giver. To view the current giver settings for all networks, use the `everdev network list` command (for details see the section [below](network-tool.md#list-registered-networks)).
108 |
109 | ## List the registered networks
110 |
111 | This command lists all registered networks, their public endpoints, and their giver addresses, if any.
112 |
113 | ```bash
114 | everdev network list
115 | ```
116 |
117 | Result:
118 |
119 | ```bash
120 | $ everdev network list
121 | Network Endpoints Giver
122 | ------------- ----------------------------------------------- ------------------------------------------------------------------
123 | se http://localhost 0:b5e9240fc2d2f1ff8cbb1d1dee7fb7cae155e5f6320e585fcc685698994a19a5
124 | dev (Default) https://devnet.evercloud.dev 0:255a3ad9dfa8aa4f3481856aafc7d79f47d50205190bd56147138740e9b177f3
125 | ```
126 |
127 | ## Set a default network
128 |
129 | This command sets a previously added network as default (initially the mainnet is used by default).
130 |
131 | ```bash
132 | everdev network default network_name
133 | ```
134 |
135 | ## Delete a network
136 |
137 | This command deletes a network from everdev registry.
138 |
139 | ```bash
140 | everdev network delete network_name
141 | ```
142 |
--------------------------------------------------------------------------------
/docs/command-line-interface/sdk.md:
--------------------------------------------------------------------------------
1 | # SDK
2 |
3 | ## See the list of available demo projects
4 |
5 | This command shows the list of available demo projects
6 |
7 | ```shell
8 | everdev js demo
9 | ```
10 |
11 | Result:
12 |
13 | ```shell
14 | $ everdev js demo
15 | Demo Description
16 | ------------ -------------------------
17 | hello-wallet Simple NodeJs Application
18 | ```
19 |
20 | ## Install demo project
21 |
22 | This command installs the specified demo project to the current directory. Proceed the instructions in the terminal to run it.
23 |
24 | ```shell
25 | everdev js demo hello-wallet
26 | ```
27 |
28 | ## Create an empty project
29 |
30 | This command creates a Node.js project with SDK latest dependencies and index.js file with main Client object creation.
31 |
32 | ```shell
33 | everdev js create test_project
34 | ```
35 |
36 | ## Create contract JS wrapper
37 |
38 | This command takes abi and, optionally, tvc file and generates a JS wrapper with abi and tvc converted into base64 that can be used further in SDK.
39 | tvc file must have the same name as abi.
40 |
41 | ```shell
42 | everdev js wrap contractName.abi.json
43 | ```
44 | The result name of the wrapper will be "ContractName||"Contract".js".
45 |
46 | See other available generation options with help command:
47 |
48 | ```shell
49 | everdev js wrap -h
50 | EverDev Version: 0.4.0
51 | Use: everdev js wrap file [options]
52 | Args:
53 | file ABI file
54 | Options:
55 | --help, -h Show command usage
56 | --print, -p Print code to console
57 | --output, -o Set output file name (default is built from source ABI file name)
58 | --export, -e Export type and options
59 | commonjs Use CommonJS modules (NodeJs)
60 | commonjs-default Use CommonJS modules (NodeJS) with default export
61 | es6 Use ES6 modules
62 | es6-default Use ES6 modules with default export
63 | ```
64 |
--------------------------------------------------------------------------------
/docs/command-line-interface/signer-tool.md:
--------------------------------------------------------------------------------
1 | # Signer Tool
2 |
3 | Signer registry is a centralized place where you can store your development keys.
4 |
5 | Each signer in registry has an unique user defined name. All everdev commands
6 | that require signing or encryption refer to the signer by name.
7 |
8 | You can mark one of the signers as a default.
9 | It can be used in signing commands without providing signer option.
10 |
11 | Signer repository management in everdev is accessible through the `signer` tool.
12 |
13 | **Note:** If you need to generate an unsigned message, you may use the option `--signer none` in any relevant commands in other controllers. Omitting the signer option altogether always means using the default signer.
14 |
15 | **Note:** Keys in the repository are stored unencrypted.
16 |
17 | ## Add a signer with randomly generated keys
18 |
19 | This command adds a signer with randomly generated keys.
20 |
21 | ```bash
22 | everdev signer generate signer_name
23 | ```
24 |
25 | See other available generation options with help command:
26 |
27 | ```bash
28 | everdev signer generate -h
29 | EverDev Version: 0.5.0
30 | Use: everdev signer generate name [options]
31 | Args:
32 | name Signer name
33 | Options:
34 | --help, -h Show command usage
35 | --mnemonic, -m Use mnemonic phrase
36 | --dictionary, -d Mnemonic dictionary
37 | 0 TON
38 | 1 English
39 | 2 Chinese Simplified
40 | 3 Chinese Traditional
41 | 4 French
42 | 5 Italian
43 | 6 Japanese
44 | 7 Korean
45 | 8 Spanish
46 | --words, -w Number of mnemonic words
47 | --force, -f Overwrite signer if already exists
48 | ```
49 |
50 | ## Add a signer with specific keys
51 |
52 | This command adds a signer with previously generated (e.g. with ever-cli) keys.
53 |
54 | ```bash
55 | everdev signer add signer_name signer_secret_key_or_seed_phrase_in_quotes
56 | ```
57 |
58 | See other available signer addition options with help command:
59 |
60 | ```bash
61 | everdev signer add -h
62 | EverDev Version: 0.5.0
63 | Use: everdev signer add name secret [options]
64 | Args:
65 | name Signer name
66 | secret Secret key or seed phrase
67 | Options:
68 | --help, -h Show command usage
69 | --dictionary, -d Mnemonic dictionary
70 | 0 TON
71 | 1 English
72 | 2 Chinese Simplified
73 | 3 Chinese Traditional
74 | 4 French
75 | 5 Italian
76 | 6 Japanese
77 | 7 Korean
78 | 8 Spanish
79 | --force, -f Overwrite signer if already exists
80 | ```
81 | **Note:** By default the dictionary is set to english, which allows using seed phrases generated by other EVERX tools, such as ever-cli.
82 |
83 |
84 | ## List registered signers
85 |
86 | This command lists all registered signers with their public keys.
87 |
88 | ```bash
89 | everdev signer list
90 | ```
91 |
92 | Result:
93 |
94 | ```bash
95 | $ everdev signer list
96 |
97 | Signer Public Key
98 | --------------- ----------------------------------------------------------------
99 | sign1 (Default) cffd3a2f1d241807b2205220a7d6df980e67a3cc7c47eba2766cdc1bbddfc0e3
100 | sign2 0fc4e781720d80f76257db333c6b6934090562418652cf30352878c87707aa94
101 | ```
102 |
103 | ## Get signer details
104 |
105 | This command lists all information (including secret data) for a specified signer.
106 |
107 | ```bash
108 | everdev signer info signer_name
109 | ```
110 |
111 | Result:
112 |
113 | ```bash
114 | $ everdev signer info sign2
115 | {
116 | "name": "sign2",
117 | "description": "",
118 | "keys": {
119 | "public": "760d69964d038997d891fca0a0407c2ffefb701e7cb2f9ff0a87fbbf1e8098f2",
120 | "secret": "72571b5a9392e6bb215b460ca3c0545c34d790e185f66f5b2e7564329ffea86c"
121 | }
122 | }
123 | ```
124 |
125 | ## Set default signer
126 |
127 | This command sets a previously added signer as default (initially the first added signer is used by default).
128 |
129 | ```bash
130 | everdev signer default signer_name
131 | ```
132 |
133 | ## Delete a signer
134 |
135 | This command deletes a previously added signer from signer registry.
136 |
137 | ```bash
138 | everdev signer delete signer_name
139 | ```
140 |
--------------------------------------------------------------------------------
/docs/command-line-interface/sold.md:
--------------------------------------------------------------------------------
1 | # Solidity compiler diver
2 |
3 | ## Version
4 |
5 | This command shows the currently installed sold version.
6 |
7 | ```shell
8 | everdev sold version
9 | ```
10 |
11 | ## Install
12 |
13 | This command installs the latest sold.
14 |
15 | ```shell
16 | everdev sold install
17 | ```
18 | The installer requires NPM to be installed, so it can install packages globally without using sudo.
19 | In case of error, manually set environment variable `PATH=$PATH:$HOME/.everdev/solidity`
20 |
21 | ## Update
22 |
23 | This command updates the sold executable to the latest version.
24 |
25 | ```shell
26 | everdev sold update
27 | ```
28 |
29 | **Attention!** Use --force option to force update of components that do not update their version.
30 |
31 | ## Set
32 |
33 | This command specifies sold version to use and downloads it if needed.
34 |
35 | ```shell
36 | everdev sold set --version 0.8.0
37 | ```
38 |
--------------------------------------------------------------------------------
/docs/command-line-interface/solidity-compiler-driver.md:
--------------------------------------------------------------------------------
1 | # Solidity Compiler Driver
2 |
3 | Everdev allows to install and manage Solidity Compiler Driver.
4 |
5 | It is a combined binary that includes Solidity compiler, TVM linker and required libraries, and streamlines the compilation process.
6 |
7 | To use Solidity Compiler Driver globally after installation via Everdev, add it to the system environment:
8 |
9 | ```shell
10 | export PATH="$HOME/.everdev/sold:$PATH"
11 | ```
12 |
13 | Then use with the following command:
14 |
15 | ```
16 | sold [OPTIONS] [INPUT]...
17 | ```
18 |
19 | To see the full documentation, use `sold --help`:
20 |
21 | ```
22 | $ sold --help
23 | sold, the Ever Solidity commandline driver
24 |
25 | Usage: sold [OPTIONS] [INPUT]...
26 |
27 | Arguments:
28 | [INPUT]... Source file name or remappings in the form of context:prefix=target
29 |
30 | Options:
31 | -c, --contract Contract to build if sources define more than one contract
32 | --base-path Use the given path as the root of the source tree instead of the root of the filesystem
33 | -i, --include-path Make an additional source directory available to the default import callback. Use this option if you want to import contracts whose location is not fixed in relation to your main source tree, e.g. third-party libraries installed using a package manager. Can be used multiple times. Can only be used if base path has a non-empty value
34 | --allowed-path Allow a given path for imports. A list of paths can be supplied by separating them with a comma
35 | -l, --lib Library to use instead of default
36 | -p, --output-prefix Prefix for output files (by default, input file stem is used as prefix)
37 | -o, --output-dir Output directory (by default, current directory is used)
38 | --print-code Print the code cell to stdout
39 | --abi-json ABI specification of the contracts
40 | --function-ids Print name and id for each public function
41 | --private-function-ids Print name and id for each private function
42 | --ast-compact-json AST of all source files in a compact JSON format
43 | --userdoc Natspec user documentation of all contracts
44 | --devdoc Natspec developer documentation of all contracts
45 | --init Set newly generated keypair
46 | --silent Mute all notifications
47 | -h, --help Print help
48 | -V, --version Print version
49 | ```
50 |
51 | {% hint style="info" %}
52 | **Note**: Version 0.68.0 and earlier versions have some dependency issues on older Linux systems. If you encounter any such issues, update to 0.69.0 or later.
53 | {% endhint %}
54 |
55 | ## Install
56 |
57 | This command installs the latest Solidity Compiler Driver
58 |
59 | ```shell
60 | everdev sold install
61 | ```
62 |
63 | To use Solidity Compiler Driver globally after installation via Everdev, add it to the system environment:
64 |
65 | ```shell
66 | export PATH="$HOME/.everdev/sold:$PATH"
67 | ```
68 |
69 | ## Version
70 |
71 | This command shows the used Solidity Compiler Driver version and list of available for download versions
72 |
73 | ```shell
74 | everdev sold version
75 | Component Version Available
76 | --------- ------- --------------------------------------------------------------
77 | driver 0.69.0 0.69.0, 0.68.0, 0.67.0, 0.66.0, 0.66.0, 0.65.0, 0.65.0, 0.64.0
78 |
79 | File path: /home//.everdev/sold/sold
80 | ```
81 |
82 | ## Set
83 |
84 | This command specifies Solidity Compiler Driver version to use and downloads it if needed.
85 |
86 | ```shell
87 | everdev sold set --version 0.69.0
88 | ```
89 |
90 | ## Update
91 |
92 | This command updates Solidity Compiler Driver version to the latest
93 |
94 | ```shell
95 | everdev sold update
96 | ```
97 |
--------------------------------------------------------------------------------
/docs/command-line-interface/solidity.md:
--------------------------------------------------------------------------------
1 | # Solidity
2 |
3 | ## Create your first contract
4 |
5 | This command creates a hello-world Solidity contract with comments that you can observe and compile.
6 |
7 | ```shell
8 | everdev sol create Contract
9 | ```
10 |
11 | ## Compile
12 |
13 | This command compiles and links a selected Solidity contract. After successful compilation you get .abi.json and .tvc files that you can later [use in your DApps to deploy and run contract methods](https://docs.everos.dev/ever-sdk/guides/work\_with\_contracts/add\_contract\_to\_your\_app).
14 |
15 | ```shell
16 | everdev sol compile Contract.sol
17 | ```
18 |
19 | To save generated assembler code use `-c` option (default is false)
20 |
21 | ```shell
22 | everdev sol compile Contract.sol -c path/to/output/file
23 | ```
24 |
25 | Assembler code will be saved in path/to/output/file with the extension `code`
26 |
27 | You can specify the output files location with the `-o` option:
28 |
29 | ```shell
30 | everdev sol compile Contract.sol -o path/to/output/file
31 | ```
32 |
33 | To make an additional source directory available to the default import callback use `-i` option:
34 |
35 | ```shell
36 | everdev sol compile Contract.sol -i path/to/importFolder
37 | ```
38 |
39 | Use this option if you want to import contracts, whose location is not fixed in relation to your main source tree, e.g. third-party libraries.
40 |
41 | Separate different paths with a comma, no space allowed.
42 |
43 | ```shell
44 | everdev sol compile Contract.sol -i path/to/folder1,path/to/folder2
45 | ```
46 |
47 | The default value is `node_modules` folder.
48 |
49 | ## Ast
50 |
51 | This command parses a ton-solidity file and creates an abstract syntax tree (AST) to the output directory.
52 |
53 | ```shell
54 | everdev sol ast Contract.sol
55 | ```
56 |
57 | To specify the ast format type, use `-f` or `--format` option:
58 |
59 | ```shell
60 | everdev sol ast-json Contract.sol -f
61 | ```
62 |
63 | To point the location of the output folder, use the `-o` or `--output-dir` option:
64 |
65 | ```shell
66 | everdev sol ast-json Contract.sol -f -o path/to/output/file
67 | ```
68 |
69 | You can make an additional source directory available to the default import callback with `-i` option:
70 |
71 | ```shell
72 | everdev sol ast Contract.sol -i path/to/importFolder
73 | ```
74 |
75 | ## Version
76 |
77 | This command shows the currently installed Solidity compiler version.
78 |
79 | ```shell
80 | everdev sol version
81 | ```
82 |
83 | ## Update
84 |
85 | This command updates the compiler and linker to the latest version.
86 |
87 | ```shell
88 | everdev sol update
89 | ```
90 |
91 | **Attention!** Use --force option to force update of components that do not update their version.
92 |
93 | ## Set
94 |
95 | This command sets the compiler and linker versions and downloads them if needed.
96 |
97 | ```shell
98 | everdev sol set --compiler 0.38.0 --linker 0.23.54
99 | ```
100 |
101 | **Attention!** Use --force option to force update of components that do not update their version.
102 |
--------------------------------------------------------------------------------
/docs/command-line-interface/testsuite4.md:
--------------------------------------------------------------------------------
1 | # TestSuite4
2 |
3 | TestSuite4 is a framework designed to simplify development and testing of TON Contracts. It contains lightweight blockchain emulator making it easy to develop contracts in a TDD-friendly style.
4 |
5 | For more information, visit [TestSuite4's documentation](https://everx-labs.github.io/TestSuite4/).
6 |
7 | :information_source: `Python 3.6 - 3.9` and `pip` required.
8 |
9 | ## Version
10 |
11 | This command shows the currently installed and available TestSuite4 framework versions.
12 |
13 | ```
14 | everdev ts4 version
15 | ```
16 |
17 | ## Install
18 |
19 | This command installs (using `pip`) TestSuite4's latest or selected version and downloads them if needed.
20 |
21 | ```bash
22 | everdev ts4 install # install latest version
23 |
24 | everdev ts4 install 0.2.0 # install version 0.2.0
25 | ```
26 |
27 | ## Update
28 |
29 | This command updates TestSuite4 to the latest version.
30 |
31 | ```
32 | everdev ts4 update
33 | ```
34 |
35 | ## Create
36 |
37 | This command creates a TestSuite4's template of the test (`TestName.py`).
38 |
39 | ```bash
40 | everdev ts4 create TestName
41 |
42 | everdev ts4 create TestName --folder tests # creates tests/TestName.py (folder must exist)
43 | ```
44 |
45 | ## Run
46 |
47 | This command runs selected test (`TestName.py`).
48 |
49 | ```
50 | everdev ts4 run TestName
51 | ```
52 |
--------------------------------------------------------------------------------
/docs/guides/creating-controller.md:
--------------------------------------------------------------------------------
1 | # Create Controller
2 |
3 | ## Content Table
4 |
5 | - [Create Controller](#create-controller)
6 | - [Content Table](#content-table)
7 | - [What a controller should and what it shouldn't to do](#what-a-controller-should-and-what-it-shouldnt-to-do)
8 | - [How to implement a Controller](#how-to-implement-a-controller)
9 | - [Controller API Reference](#controller-api-reference)
10 |
11 | Currently all the controllers must be implemented inside of the `everdev` package.
12 |
13 | To create a new controller:
14 |
15 | - Clone `git@github.com:everx-labs/everdev.git`.
16 | - Create and checkout branch for the new controller.
17 | - Create a folder under `src/controllers`.
18 | - Implement the controller code.
19 | - Include the new controller in file `src/controllers/index.js`.
20 | - Create pull request.
21 |
22 | ## What a controller should and what it shouldn't to do
23 |
24 | Controller should:
25 |
26 | - Expose functionality to the user as a list of commands.
27 | - Install the required tool components on demand (on first usage).
28 | - Start and stop the tool components that acts like a demons.
29 | - Define three commands to control the tool version:
30 | - `version` to show the currently installed tool version;
31 | - `update` to update the tool to the latest available version;
32 | - `use` to select the specified tool version as the current version.
33 |
34 | Controller shouldn't:
35 |
36 | - Implement tool functionality itself. Controller is a connector between the user and the existing development tool.
37 | - Implement user interaction itself. All user interaction must be implemented exactly in the terms of everdev extensibility.
38 |
39 | ## How to implement a Controller
40 |
41 | Create a folder for a new controller:
42 |
43 | ```shell
44 | mkdir src/controllers/foo
45 | cd src/controllers/foo
46 | ```
47 |
48 | Create `index.ts` with the controller's definition:
49 |
50 | ```ts
51 | import { ToolController } from "../../core";
52 | import { versionCommand } from "./version";
53 | import { updateCommand } from "./update";
54 | import { runCommand } from "./run";
55 |
56 | export const Foo: ToolController = {
57 | name: "foo",
58 | title: "Foo Tool",
59 | commands: [
60 | versionCommand,
61 | updateCommand,
62 | runCommand,
63 | ],
64 | };
65 | ```
66 |
67 | Create `installer.ts` to implement all the code related to the tool installation:
68 |
69 | ```ts
70 | import path from "path";
71 | import fs from "fs";
72 | import { Terminal, everdevHome } from "../../core";
73 |
74 | function fooHome() {
75 | return path.resolve(everdevHome(), "foo");
76 | }
77 |
78 | async function ensureInstalled(terminal: Terminal) {
79 | }
80 |
81 | export async function getVersion(): Promise {
82 | return "1.0.0";
83 | }
84 |
85 | export async function updateVersion(terminal: Terminal) {
86 | if (fs.existsSync(fooHome())) {
87 | fs.rmdirSync(fooHome(), { recursive: true });
88 | }
89 | ensureInstalled(terminal);
90 | }
91 |
92 | export async function runFoo(terminal: Terminal, workDir: string, args: string[]): Promise {
93 | ensureInstalled(terminal);
94 | terminal.log("Foo succeeded");
95 | };
96 | ```
97 |
98 | Create `version.ts` command handler:
99 |
100 | ```ts
101 | import { getVersion } from "./installer";
102 | import { Command, Terminal } from "../../core";
103 |
104 | export const versionCommand: Command = {
105 | name: "version",
106 | title: "Show Foo Version",
107 | async run(terminal: Terminal, _args: {}): Promise {
108 | terminal.log(await getVersion());
109 | },
110 | };
111 | ```
112 |
113 | Create `update.ts` command handler:
114 |
115 | ```ts
116 | import { updateVersion } from "./installer";
117 | import { Command, Terminal } from "../../core";
118 |
119 | export const versionCommand: Command = {
120 | name: "update",
121 | title: "Update Foo Version",
122 | async run(terminal: Terminal, _args: {}): Promise {
123 | await updateVersion(terminal);
124 | },
125 | };
126 | ```
127 |
128 | Create `run.ts` command handler:
129 |
130 | ```ts
131 | import { runFoo } from "./installer";
132 | import { Command, Terminal } from "../../core";
133 |
134 | export const runCommand: Command = {
135 | name: "run",
136 | title: "Run Foo",
137 | async run(terminal: Terminal, args: {}): Promise {
138 | await runFoo(terminal, args);
139 | },
140 | };
141 | ```
142 |
143 | ## Controller API Reference
144 |
145 | You can find API reference in form of TSDoc in `src/core/index.ts`.
146 |
--------------------------------------------------------------------------------
/docs/troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | Here are some solutions to frequently encountered problems.
4 |
5 | ## EACCESS errors during installation
6 |
7 | These errors can occur, if npm was installed without the use of a version manager.
8 |
9 | Refer to [this article](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally) for ways to resolve the issue.
10 |
11 | ## command not found: everdev
12 |
13 | This error may happen because `PATH` environment variable was not correctly updated to contain path to Node.js binary.
14 |
15 | If you use Linux, ensure the following command is in your `~/.bashrc` for bash shell or `~/.zshrc` for zsh shell:
16 |
17 | ```
18 | export PATH=~/.npm-global/bin:$PATH
19 | ```
20 |
21 | If you have installed Node.js using Homebrew on MacOS, npm binaries could be found in `/usr/local/share/npm/bin`. So, in your `~/.zshrc` file add the following:
22 |
23 | ```
24 | export PATH=/usr/local/share/npm/bin:$PATH
25 | ```
26 |
27 | If you use Windows, add path to NodeJS bin directory via environment variables settings dialogue and relaunch console window.
28 |
29 | Additionally, make sure [permissions are alright](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally).
30 |
31 | ## Unspecified Error on `everdev sol compile` in Windows 10
32 |
33 | 1. Run \Users\UserName\everdev\solidity\solc.exe and review error messages.
34 | 2. Update Visual Studio components and make sure [vc\_redist is installed](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0).
35 |
36 | ## Evernode SE: Couldn’t connect to Docker daemon
37 |
38 | This error occurs in two cases. Either the docker daemon isn't running, or current user doesn't have rights to access docker.
39 |
40 | You can [fix the rights](https://docs.docker.com/engine/install/linux-postinstall/) issue either by running relevant commands as the superuser or adding the user to the `docker` group:
41 |
42 | ```
43 | sudo usermod -a -G docker $USER
44 | ```
45 |
46 | Make sure to restart the system or log out and back in, for the new group settings to take effect.
47 |
48 | ## Evernode SE Error: connect ENOENT /var/run/docker.sock
49 |
50 | Getting this error means docker service is not running or missing due to incorrect Docker installation, partiularly in the case of Docker Desktop. Try reinstalling Docker and making sure the [daemon](https://docs.docker.com/config/daemon/start/) is running.
51 |
52 | ## Evernode SE: Ever.live at localhost isn't available
53 |
54 | If you use certain adblockers, after you have started Evernode SE the Ever Live explorer at [http://127.0.0.1/landing](http://127.0.0.1/landing) might fail to load (you get a rotating icon and various warnings and errors in the console).
55 |
56 | ## After everdev is installed on Ubuntu WSL on Windows 10 old version is there
57 |
58 | This issue can occur if npm was installed without correct permissions for Linux/Ubuntu. Refer to [this article](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally) for ways to resolve it.
59 |
60 | After it is done, reload terminal and install everdev via `npm i everdev -g` again.
61 |
--------------------------------------------------------------------------------
/docs/use-in-js-applications.md:
--------------------------------------------------------------------------------
1 | # Use in JS applications
2 |
3 | You can easily use everdev as a regular npm package in your JS applications.
4 |
5 | Just add dependency into you `package.json`:
6 |
7 | ```shell
8 | npm i -s everdev
9 | ```
10 |
11 | And then run any command from everdev:
12 |
13 | ```js
14 | const { consoleTerminal, runCommand } = require("everdev");
15 | const path = require("path");
16 |
17 | async function main() {
18 | await runCommand(consoleTerminal, "sol compile", {
19 | file: path.resolve(__dirname, "Hello.sol")
20 | });
21 | }
22 |
23 | main();
24 | ```
25 |
--------------------------------------------------------------------------------
/docs/view-controller-info.md:
--------------------------------------------------------------------------------
1 | # View controller info
2 |
3 | This command displays a summary of all controller configurations.
4 |
5 | ```
6 | everdev info
7 | ```
8 | Output example:
9 |
10 | $ everdev info
11 |
12 | ```
13 | C++ compiler
14 |
15 | Component Version Available
16 | --------- ------- ---------
17 | clang 7.0.0 7.0.0
18 |
19 | Solidity Compiler
20 |
21 | Component Available
22 | --------- ----------------------------------------------
23 | compiler 0.42.0, 0.41.0, 0.40.0, 0.39.0, 0.38.2, 0.38.1
24 | linker 0.3.0, 0.1.0
25 | stdlib 0.42.0, 0.41.0, 0.40.0, 0.39.0, 0.38.2, 0.38.1
26 |
27 | EVER OS SE
28 |
29 | Instance State Version GraphQL Port Docker Container Docker Image
30 | -------- ------------- ------- ------------ -------------------- -----------------------
31 | default not installed 0.27 80 tonlabs-tonos-se-test tonlabs/local-node:0.27
32 |
33 | Network Registry
34 |
35 | Network Endpoints Giver
36 | ------------- ----------------------------------------------- ------------------------------------------------------------------
37 | se http://localhost 0:b5e9240fc2d2f1ff8cbb1d1dee7fb7cae155e5f6320e585fcc685698994a19a5
38 | dev (Default) net.ton.dev, net1.ton.dev, net5.ton.dev 0:255a3ad9dfa8aa4f3481856aafc7d79f47d50205190bd56147138740e9b177f3
39 | main main.ton.dev, main2.ton.dev, main3.ton.dev, ...
40 |
41 | Signer Registry
42 |
43 | Signer Public Key
44 | -------------- ----------------------------------------------------------------
45 | surf 8534c46f7a135058773fa1298cb3a299a5ddd40dafe41cb06c64f274da360bfb
46 | test (Default) ad4bf7bd8da244932c52127a943bfa9217b6e215c1b3307272283c4d64f34486
47 | test2 5c2e348c5caeb420a863dc5e972f897ebe5ee899a6ef2a8299aac352eca4380a
48 |
49 | EVER OS CLI
50 |
51 | Component Version Available
52 | --------- ------- --------------------------------------------------------------------------------
53 | tonoscli 0.11.3 0.11.4, 0.11.3, 0.11.2, 0.11.1, 0.11.0, 0.10.1, 0.10.0, 0.9.2, 0.9.1, 0.9.0, ...
54 | ```
55 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | globals: {
3 | "ts-jest": {
4 | tsconfig: "tsconfig.json",
5 | },
6 | },
7 | moduleFileExtensions: ["ts", "js"],
8 | transform: {
9 | "^.+\\.(ts|tsx)$": "ts-jest",
10 | },
11 | modulePathIgnorePatterns: [".*\\.d\\.ts"],
12 | testMatch: ["**/test/**/*.+(ts)", "**/__tests__/**/*.+(ts|tsx)"],
13 | testEnvironment: "node",
14 | }
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "everdev",
3 | "version": "1.7.1",
4 | "description": "Everscale Dev Environment",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/everx-labs/everdev.git"
10 | },
11 | "scripts": {
12 | "prepublishOnly": "npm i && tsc",
13 | "everdev": "node ./cli.js",
14 | "format": "prettier --write 'src/**/*.ts'",
15 | "eslint": "eslint \"**/*.ts\"",
16 | "eslint-fix": "eslint \"**/*.ts\" --fix",
17 | "tsc": "tsc",
18 | "build": "rimraf dist && npm run eslint && tsc --project tsconfig.build.json",
19 | "test": "jest -i --forceExit --detectOpenHandles --coverage --verbose"
20 | },
21 | "bin": {
22 | "everdev": "./cli.js"
23 | },
24 | "keywords": [
25 | "Free",
26 | "TON",
27 | "Ever",
28 | "EverScale",
29 | "Freeton",
30 | "Dev",
31 | "Development",
32 | "EVER OS",
33 | "EVEROS"
34 | ],
35 | "author": "EverX Labs Ltd",
36 | "license": "Apache-2.0",
37 | "licenses": [
38 | {
39 | "type": "Apache-2.0",
40 | "url": "http://www.apache.org/licenses/LICENSE-2.0"
41 | }
42 | ],
43 | "homepage": "https://docs.ton.dev/",
44 | "engines": {
45 | "node": ">=6"
46 | },
47 | "dependencies": {
48 | "@eversdk/appkit": "^0.3.4",
49 | "@eversdk/core": "^1.41.1",
50 | "@eversdk/lib-node": "^1.41.1",
51 | "chalk": "^2.4.2",
52 | "dockerode": "^3.3.1",
53 | "fs-extra": "^9.1.0",
54 | "mv": "^2.1.1",
55 | "request": "^2.88.2",
56 | "unzip-stream": "^0.3.1"
57 | },
58 | "devDependencies": {
59 | "@babel/preset-env": "^7.14.7",
60 | "@babel/preset-typescript": "^7.14.5",
61 | "@types/dockerode": "^3.2.2",
62 | "@types/fs-extra": "^9.0.8",
63 | "@types/jest": "^27.4.1",
64 | "@types/mv": "^2.1.1",
65 | "@types/node": "^16.0.1",
66 | "@types/request": "^2.48.5",
67 | "@types/unzip-stream": "^0.3.0",
68 | "@typescript-eslint/eslint-plugin": "^5.19.0",
69 | "@typescript-eslint/parser": "^5.19.0",
70 | "caxa": "^1.0.0",
71 | "eslint": "^7.30.0",
72 | "eslint-config-prettier": "^8.5.0",
73 | "eslint-plugin-jest": "^26.1.4",
74 | "eslint-plugin-prettier": "^4.0.0",
75 | "husky": "^4.3.8",
76 | "jest": "^27.5.1",
77 | "lint-staged": "^12.3.8",
78 | "prettier": "^2.3.2",
79 | "rimraf": "^3.0.2",
80 | "ts-jest": "^27.1.4",
81 | "typescript": "^4.8.4"
82 | },
83 | "husky": {
84 | "hooks": {
85 | "pre-commit": "lint-staged"
86 | }
87 | },
88 | "lint-staged": {
89 | "*.ts": [
90 | "npm run eslint",
91 | "npm run format"
92 | ]
93 | }
94 | }
--------------------------------------------------------------------------------
/src/__tests__/addProjectId.ts:
--------------------------------------------------------------------------------
1 | import { transformEndpoint } from "../controllers/contract/accounts"
2 | import { doneTests, initTests } from "./init"
3 |
4 | beforeAll(initTests)
5 | afterAll(doneTests)
6 |
7 | test("Transform different endpoints. Add projectId", async () => {
8 | const endpoints = [
9 | "eri01.net.everos.dev",
10 | "https://eri01.net.everos.dev/",
11 | "eri01.net.everos.dev/",
12 | "https://eri01.net.everos.dev/graphql/",
13 | "eri01.net.everos.dev/graphql",
14 | ]
15 | const result = endpoints.map(transformEndpoint("myId"))
16 | expect(result[0]).toEqual("eri01.net.everos.dev/myId")
17 | expect(result[1]).toEqual("https://eri01.net.everos.dev/myId")
18 | expect(result[2]).toEqual("eri01.net.everos.dev/myId")
19 | expect(result[3]).toEqual("https://eri01.net.everos.dev/myId")
20 | expect(result[4]).toEqual("eri01.net.everos.dev/myId")
21 | })
22 | test("Transform different endpoints. Add void projectId", async () => {
23 | const endpoints = [
24 | "eri01.net.everos.dev",
25 | "https://eri01.net.everos.dev/",
26 | "eri01.net.everos.dev/",
27 | "https://eri01.net.everos.dev/graphql/",
28 | "eri01.net.everos.dev/graphql",
29 | ]
30 | const result = endpoints.map(transformEndpoint(undefined))
31 | expect(result[0]).toEqual("eri01.net.everos.dev")
32 | expect(result[1]).toEqual("https://eri01.net.everos.dev")
33 | expect(result[2]).toEqual("eri01.net.everos.dev")
34 | expect(result[3]).toEqual("https://eri01.net.everos.dev")
35 | expect(result[4]).toEqual("eri01.net.everos.dev")
36 | })
37 |
--------------------------------------------------------------------------------
/src/__tests__/checkArgs.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs"
2 | import path from "path"
3 |
4 | import { doneTests, initTests, deleteFolderRecursive } from "./init"
5 | import { StringTerminal, consoleTerminal, runCommand } from ".."
6 |
7 | const outPath = path.resolve(__dirname, "..", "..", `${Date.now()}-tmp`)
8 |
9 | beforeAll(initTests)
10 | afterAll(doneTests)
11 | beforeEach(() => deleteFolderRecursive(outPath))
12 | afterEach(() => deleteFolderRecursive(outPath))
13 | /*
14 | test("Should create HelloWallet.tvc in user defined output directory", async () => {
15 | await runCommand(consoleTerminal, "sol update", {})
16 |
17 | const solPath = path.resolve(
18 | __dirname,
19 | "..",
20 | "..",
21 | "contracts",
22 | "HelloWallet.sol",
23 | )
24 |
25 | const terminal = new StringTerminal()
26 | await runCommand(terminal, "sol compile", {
27 | file: solPath,
28 | outputDir: outPath,
29 | })
30 | expect(terminal.stderr.trim()).toEqual("")
31 |
32 | const tvcFile = path.resolve(outPath, "HelloWallet.tvc")
33 | expect(fs.existsSync(tvcFile)).toBeTruthy()
34 | })
35 | */
36 | test("Should warn user to use options in camelCase", async () => {
37 | const solPath = path.resolve(
38 | __dirname,
39 | "..",
40 | "..",
41 | "contracts",
42 | "HelloWallet.sol",
43 | )
44 | const terminal = new StringTerminal()
45 | try {
46 | await runCommand(terminal, "sol compile", {
47 | file: solPath,
48 | "hello-world": "hi!",
49 | })
50 | throw Error("This function didn't throw")
51 | } catch (err: any) {
52 | expect(err.message).toMatch(/Unknow option: hello-world/)
53 | }
54 | })
55 |
--------------------------------------------------------------------------------
/src/__tests__/checkNewVersion.ts:
--------------------------------------------------------------------------------
1 | import {
2 | createLatestVerFile,
3 | getUpdateIsAvailableMsg,
4 | } from "../everdev/checkNewVersion"
5 | import { doneTests, initTests } from "./init"
6 |
7 | beforeAll(initTests)
8 | afterAll(doneTests)
9 |
10 | test("Shoud see message of the day only once", async () => {
11 | await createLatestVerFile("everdev")
12 | const result1 = getUpdateIsAvailableMsg("everdev", "0.1.0")
13 | expect(result1.length).toBeGreaterThan(0)
14 | const result2 = getUpdateIsAvailableMsg("everdev", "0.1.0")
15 | expect(result2.length).toEqual(0)
16 | })
17 |
--------------------------------------------------------------------------------
/src/__tests__/contracts.ts:
--------------------------------------------------------------------------------
1 | import { doneTests, initTests } from "./init"
2 | import path from "path"
3 | import { ParamParser } from "../controllers/contract/param-parser"
4 |
5 | beforeAll(initTests)
6 | afterAll(doneTests)
7 |
8 | function dataPath(name: string): string {
9 | return path.resolve(__dirname, "..", "..", "src", "__tests__", "data", name)
10 | }
11 |
12 | test("Contract alone args file", async () => {
13 | const file = dataPath("contracts-input-alone.json")
14 | const abi = { name: "a", type: "string[]" }
15 | const args = ParamParser.components(abi, `@${file}`)
16 | expect(args).toEqual([1, 2, 3])
17 | })
18 |
19 | test("Contract multi args file", async () => {
20 | const file = dataPath("contracts-input.json")
21 | const abi = { name: "a", type: "string[]" }
22 | const args = ParamParser.components(abi, `@${file}@test1`)
23 | expect(args).toEqual({ a: [1, 2, 3] })
24 | const args2 = ParamParser.components(abi, `@${file}@test2`)
25 | expect(args2).toEqual({ b: [1, 2, 3] })
26 | const args3 = ParamParser.components(abi, `@${file}@test2.b`)
27 | expect(args3).toEqual([1, 2, 3])
28 | })
29 |
--------------------------------------------------------------------------------
/src/__tests__/data/contracts-input-alone.json:
--------------------------------------------------------------------------------
1 | [1, 2, 3]
2 |
3 |
--------------------------------------------------------------------------------
/src/__tests__/data/contracts-input.json:
--------------------------------------------------------------------------------
1 | {
2 | "test1": {
3 | "a": [1, 2, 3]
4 | },
5 | "test2": {
6 | "b": [1, 2, 3]
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/__tests__/init.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-empty-function */
2 | import { everdevInit, everdevDone, everdevHome, writeTextFile } from ".."
3 | import path from "path"
4 | import fs from "fs"
5 | import os from "os"
6 |
7 | jest.setTimeout(500000)
8 |
9 | test("init", () => {})
10 |
11 | export function tempFolder(): string {
12 | const temp = path.resolve(everdevHome(), "_temp")
13 | if (!fs.existsSync(temp)) {
14 | fs.mkdirSync(temp, { recursive: true })
15 | }
16 | return temp
17 | }
18 |
19 | export function writeTempText(name: string, text: string): string {
20 | const filePath = path.resolve(tempFolder(), name)
21 | writeTextFile(filePath, text)
22 | return filePath
23 | }
24 |
25 | export function copyToTemp(source: string): string {
26 | const filePath = path.resolve(tempFolder(), path.basename(source))
27 | fs.copyFileSync(source, filePath)
28 | return filePath
29 | }
30 |
31 | export function writeTempJson(name: string, json: unknown): string {
32 | return writeTempText(name, JSON.stringify(json, undefined, " "))
33 | }
34 |
35 | export function deleteFiles(files: string[]) {
36 | files.forEach(file => {
37 | if (fs.existsSync(file)) {
38 | fs.unlinkSync(file)
39 | }
40 | })
41 | }
42 |
43 | export function initTests() {
44 | const home = path.resolve(os.homedir(), ".everdev_test")
45 | everdevInit({
46 | home,
47 | })
48 | deleteFolderRecursive(path.resolve(home, "_temp"))
49 | deleteFiles([
50 | path.resolve(home, "signer", "registry.json"),
51 | path.resolve(home, "network", "registry.json"),
52 | path.resolve(home, "se", "config.json"),
53 | path.resolve(home, ".lastrun"),
54 | path.resolve(home, ".latest"),
55 | ])
56 | }
57 |
58 | export function doneTests() {
59 | everdevDone()
60 | }
61 |
62 | export function deleteFolderRecursive(directoryPath: string) {
63 | if (fs.existsSync(directoryPath)) {
64 | fs.readdirSync(directoryPath).forEach(file => {
65 | const curPath = path.join(directoryPath, file)
66 | if (fs.lstatSync(curPath).isDirectory()) {
67 | deleteFolderRecursive(curPath)
68 | } else {
69 | fs.unlinkSync(curPath)
70 | }
71 | })
72 | fs.rmdirSync(directoryPath)
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/__tests__/network.ts:
--------------------------------------------------------------------------------
1 | import { doneTests, initTests } from "./init"
2 | import { runCommand, consoleTerminal } from ".."
3 | import { NetworkRegistry } from "../controllers/network/registry"
4 | import { SignerRegistry } from "../controllers/signer/registry"
5 |
6 | import * as knownContracts from "../core/known-contracts"
7 |
8 | beforeAll(async () => {
9 | await initTests()
10 | await new SignerRegistry().addSecretKey(
11 | "alice",
12 | "",
13 | "172af540e43a524763dd53b26a066d472a97c4de37d5498170564510608250c3",
14 | true,
15 | )
16 | })
17 | afterAll(doneTests)
18 |
19 | test("Add network giver by address", async () => {
20 | const mock = jest.spyOn(knownContracts, "knownContractFromAddress")
21 | mock.mockReturnValue(
22 | Promise.resolve(knownContracts.KnownContracts["GiverV2"]),
23 | )
24 | await runCommand(consoleTerminal, "network giver", {
25 | name: "se",
26 | address:
27 | "0:b5e9240fc2d2f1ff8cbb1d1dee7fb7cae155e5f6320e585fcc685698994a19a5",
28 | type: "GiverV2",
29 | signer: "alice",
30 | })
31 | expect(new NetworkRegistry().get("se").giver?.name).toEqual("GiverV2")
32 | })
33 |
34 | test("Add network giver by type", async () => {
35 | await runCommand(consoleTerminal, "network giver", {
36 | name: "se",
37 | type: "GiverV2",
38 | signer: "alice",
39 | })
40 | expect(new NetworkRegistry().get("se").giver?.name).toEqual("GiverV2")
41 |
42 | await runCommand(consoleTerminal, "network giver", {
43 | name: "se",
44 | type: "SafeMultisigWallet",
45 | signer: "alice",
46 | })
47 | expect(new NetworkRegistry().get("se").giver?.name).toEqual(
48 | "SafeMultisigWallet",
49 | )
50 | await runCommand(consoleTerminal, "network giver", {
51 | name: "se",
52 | type: "MsigV2",
53 | signer: "alice",
54 | })
55 | expect(new NetworkRegistry().get("se").giver?.name).toEqual("MsigV2")
56 | })
57 |
58 | test("Add network giver error", async () => {
59 | try {
60 | await runCommand(consoleTerminal, "network giver", {
61 | name: "se",
62 | type: "NotExist",
63 | signer: "alice",
64 | })
65 | expect(true).toBe(false)
66 | } catch (error: any) {
67 | expect(error.message).toBe(
68 | "Can not resolve giver address: unknown giver type NotExist.",
69 | )
70 | }
71 | })
72 |
73 | test("Add credentials", async () => {
74 | await runCommand(consoleTerminal, "network credentials", {
75 | name: "se",
76 | project: "pro123",
77 | accessKey: "key456",
78 | })
79 | const registry = new NetworkRegistry().get("se")
80 | expect(registry.credentials?.project).toEqual("pro123")
81 | expect(registry.credentials?.accessKey).toEqual("key456")
82 | })
83 |
84 | test("Clear credentials", async () => {
85 | await runCommand(consoleTerminal, "network credentials", {
86 | name: "se",
87 | clear: true,
88 | })
89 | const registry = new NetworkRegistry().get("se")
90 | expect(registry.credentials?.project).toBeUndefined()
91 | })
92 |
--------------------------------------------------------------------------------
/src/__tests__/parser.ts:
--------------------------------------------------------------------------------
1 | import { CommandLine } from "../cli"
2 | import { doneTests, initTests } from "./init"
3 | import {
4 | Solidity,
5 | solidityCompileCommand,
6 | solidityCreateCommand,
7 | } from "../controllers/solidity"
8 |
9 | import { NetworkTool, networkGiverCommand } from "../controllers/network"
10 | beforeAll(initTests)
11 | afterAll(doneTests)
12 |
13 | test("Should throw", async () => {
14 | const parser = new CommandLine()
15 | try {
16 | await parser.parse(["nono"])
17 | } catch (err) {
18 | expect(err.message).toMatch(/Unknown tool/)
19 | }
20 | })
21 |
22 | test("everdev --help", async () => {
23 | const parser = new CommandLine()
24 | await parser.parse(["--help"])
25 | expect(parser.args.help).toBe(true)
26 | })
27 |
28 | test("everdev sol", async () => {
29 | const parser = new CommandLine()
30 | await parser.parse(["sol"])
31 | const { controller, command, args } = parser
32 | expect(controller).toEqual(Solidity)
33 | expect(command).toBeUndefined()
34 | expect(args).toEqual({})
35 | })
36 |
37 | test("everdev sol compile, should throw", async () => {
38 | const parser = new CommandLine()
39 | try {
40 | await parser.parse(["sol", "compile"])
41 | } catch (err) {
42 | expect(err.message).toMatch(/Missing required file/)
43 | }
44 | })
45 |
46 | test("everdev sol compile a.sol", async () => {
47 | const parser = new CommandLine()
48 | await parser.parse(["sol", "compile", "a.sol"])
49 | const { controller, command, args } = parser
50 | expect(controller).toEqual(Solidity)
51 | expect(command).toEqual(solidityCompileCommand)
52 | expect(args).toEqual({
53 | code: false,
54 | file: "a.sol",
55 | basePath: ".",
56 | includePath: "node_modules",
57 | outputDir: "",
58 | })
59 | })
60 |
61 | test("everdev sol compile a.sol b.sol --output-dir somedir", async () => {
62 | const parser = new CommandLine()
63 | await parser.parse([
64 | "sol",
65 | "compile",
66 | "a.sol",
67 | "b.sol",
68 | "--output-dir",
69 | "somedir",
70 | ])
71 | const { controller, command, args } = parser
72 | expect(controller).toEqual(Solidity)
73 | expect(command).toEqual(solidityCompileCommand)
74 | expect(args).toEqual({
75 | code: false,
76 | file: "a.sol b.sol",
77 | basePath: ".",
78 | includePath: "node_modules",
79 | outputDir: "somedir",
80 | })
81 | })
82 |
83 | test("everdev create a.sol", async () => {
84 | const parser = new CommandLine()
85 | await parser.parse(["sol", "create", "a.sol"])
86 | const { controller, command, args } = parser
87 | expect(controller).toEqual(Solidity)
88 | expect(command).toEqual(solidityCreateCommand)
89 | expect(args).toEqual({
90 | name: "a.sol",
91 | folder: process.cwd(),
92 | })
93 | })
94 |
95 | test("everdev create a.sol b.sol, should throw", async () => {
96 | const parser = new CommandLine()
97 | try {
98 | await parser.parse(["sol", "create", "a.sol", "b.sol"])
99 | throw Error("Shouldn't resolve!")
100 | } catch (err) {
101 | expect(err.message).toMatch(/Unexpected argument/)
102 | }
103 | })
104 |
105 | test("everdev network add giver with address in negative workchain", async () => {
106 | const parser = new CommandLine()
107 | await parser.parse([
108 | "network",
109 | "giver",
110 | "networkName",
111 | "-2:1111111111111111111111111111111111111111111111111111111111111111",
112 | "-s",
113 | "seGiver",
114 | "-t",
115 | "GiverV1",
116 | ])
117 | const { controller, command, args } = parser
118 | expect(controller).toEqual(NetworkTool)
119 | expect(command).toEqual(networkGiverCommand)
120 | expect(args).toEqual({
121 | name: "networkName",
122 | address:
123 | "-2:1111111111111111111111111111111111111111111111111111111111111111",
124 | signer: "seGiver",
125 | type: "GiverV1",
126 | value: "",
127 | })
128 | })
129 |
130 | test("everdev network add giver with address in positive workchain", async () => {
131 | const parser = new CommandLine()
132 | await parser.parse([
133 | "network",
134 | "giver",
135 | "networkName",
136 | "0:1111111111111111111111111111111111111111111111111111111111111111",
137 | "-s",
138 | "seGiver",
139 | "-t",
140 | "GiverV1",
141 | ])
142 | const { controller, command, args } = parser
143 | expect(controller).toEqual(NetworkTool)
144 | expect(command).toEqual(networkGiverCommand)
145 | expect(args).toEqual({
146 | name: "networkName",
147 | address:
148 | "0:1111111111111111111111111111111111111111111111111111111111111111",
149 | signer: "seGiver",
150 | type: "GiverV1",
151 | value: "",
152 | })
153 | })
154 |
155 | test("everdev network add giver with malformed address in negative workchain", async () => {
156 | const parser = new CommandLine()
157 | try {
158 | await parser.parse([
159 | "network",
160 | "giver",
161 | "networkName",
162 | "-1w:123",
163 | "-s",
164 | "seGiver",
165 | "-t",
166 | "GiverV1",
167 | ])
168 | throw Error("Shouldn't resolve!")
169 | } catch (err) {
170 | expect(err.message).toMatch(/Unknown option/)
171 | }
172 | })
173 |
--------------------------------------------------------------------------------
/src/__tests__/se.ts:
--------------------------------------------------------------------------------
1 | import { doneTests, initTests } from "./init"
2 | import { runCommand } from "../controllers"
3 | import { consoleTerminal } from "../core/utils"
4 |
5 | beforeAll(initTests)
6 | afterAll(doneTests)
7 |
8 | test("Use custom docker image", async () => {
9 | await runCommand(consoleTerminal, "se set", {
10 | instance: "se1",
11 | image: "tonlabs/local-node:0.28.1",
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/src/__tests__/signer.ts:
--------------------------------------------------------------------------------
1 | import { doneTests, initTests, writeTempJson } from "./init"
2 | import { consoleTerminal } from ".."
3 | import { signerAddCommand } from "../controllers/signer"
4 | import { SignerRegistry } from "../controllers/signer/registry"
5 | import { TonClient } from "@eversdk/core"
6 |
7 | beforeAll(initTests)
8 | afterAll(doneTests)
9 |
10 | test("Add signer with secret key", async () => {
11 | const keys = await TonClient.default.crypto.generate_random_sign_keys()
12 | await signerAddCommand.run(consoleTerminal, {
13 | name: "from_secret_key",
14 | secret: keys.secret,
15 | })
16 | expect(new SignerRegistry().get("from_secret_key").keys).toEqual(keys)
17 | })
18 |
19 | test("Add signer with keys file", async () => {
20 | const keys = await TonClient.default.crypto.generate_random_sign_keys()
21 | const keysPath = writeTempJson("keys.json", keys)
22 | await signerAddCommand.run(consoleTerminal, {
23 | name: "from_keys_file",
24 | secret: keysPath,
25 | })
26 | expect(new SignerRegistry().get("from_keys_file").keys).toEqual(keys)
27 | })
28 |
29 | test("Add signer with the same name should throw", async () => {
30 | const keys = await TonClient.default.crypto.generate_random_sign_keys()
31 | const keysPath = writeTempJson("keys.json", keys)
32 | expect(() =>
33 | signerAddCommand.run(consoleTerminal, {
34 | name: "from_keys_file",
35 | secret: keysPath,
36 | }),
37 | ).rejects.toThrow(/Signer with name "from_keys_file" already exists/)
38 | })
39 |
40 | test("Add signer with the same name and 'force' option", async () => {
41 | const keys = await TonClient.default.crypto.generate_random_sign_keys()
42 | const keysPath = writeTempJson("keys.json", keys)
43 | await signerAddCommand.run(consoleTerminal, {
44 | name: "from_keys_file",
45 | secret: keysPath,
46 | force: true,
47 | })
48 | expect(new SignerRegistry().get("from_keys_file").keys).toEqual(keys)
49 | })
50 |
51 | test("Add invalid keys from file", async () => {
52 | const keysPath = writeTempJson("keys.json", {
53 | public: "a1855789cdab95ba2776450aa0215f6a1f9442770e30d17c1d3589a3ef08d66b",
54 | secret: "0af4fb5e63d53211cb112512sb",
55 | })
56 | expect(() =>
57 | signerAddCommand.run(consoleTerminal, {
58 | name: "from_keys_file",
59 | secret: keysPath,
60 | }),
61 | ).rejects.toThrow(/Invalid keys file/)
62 | })
63 |
--------------------------------------------------------------------------------
/src/__tests__/sol.ts:
--------------------------------------------------------------------------------
1 | import { copyToTemp, doneTests, initTests } from "./init"
2 | import { consoleTerminal, runCommand, StringTerminal } from ".."
3 | import path from "path"
4 | import fs from "fs"
5 |
6 | beforeAll(initTests)
7 | afterAll(doneTests)
8 | /*
9 | test("Hide linker output", async () => {
10 | await runCommand(consoleTerminal, "sol update", {})
11 | const terminal = new StringTerminal()
12 | const solPath = copyToTemp(
13 | path.resolve(__dirname, "..", "..", "contracts", "HelloWallet.sol"),
14 | )
15 | await runCommand(terminal, "sol compile", {
16 | file: solPath,
17 | })
18 | expect(terminal.stdout.trim()).toEqual("")
19 | })
20 | */
21 | test("AST of all source files in a JSON", async () => {
22 | await runCommand(consoleTerminal, "sol update", {})
23 | const terminal = new StringTerminal()
24 | const solPath = path.resolve(
25 | __dirname,
26 | "..",
27 | "..",
28 | "contracts",
29 | "HelloWallet.sol",
30 | )
31 | const astPath = path.resolve(
32 | __dirname,
33 | "..",
34 | "..",
35 | "HelloWallet.sol_json.ast",
36 | )
37 | // Remove output file if exists
38 | try {
39 | fs.unlinkSync(astPath)
40 | } catch (_) {}
41 |
42 | await runCommand(terminal, "sol ast --format json", {
43 | file: solPath,
44 | })
45 | const ast = fs.readFileSync(astPath, "utf-8")
46 | expect(ast.length).toBeGreaterThan(0)
47 | expect(typeof JSON.parse(ast)).toEqual("object")
48 | })
49 |
--------------------------------------------------------------------------------
/src/__tests__/wrap.ts:
--------------------------------------------------------------------------------
1 | import path from "path"
2 |
3 | import { doneTests, initTests, deleteFiles } from "./init"
4 | import { StringTerminal, runCommand } from ".."
5 |
6 | beforeAll(initTests)
7 | afterAll(doneTests)
8 | /*
9 | test("Shoud create HelloWallet.abi.json file", async () => {
10 | await runCommand(consoleTerminal, "sol update", {})
11 | const solPath = path.resolve(
12 | __dirname,
13 | "..",
14 | "..",
15 | "contracts",
16 | "HelloWallet.sol",
17 | )
18 | const terminal = new StringTerminal()
19 | await runCommand(terminal, "sol compile", {
20 | file: solPath,
21 | })
22 | expect(terminal.stderr.trim()).toEqual("")
23 | })
24 | test("Shoud create HelloWalletContract.js file", async () => {
25 | const wrappedJs = path.resolve(
26 | __dirname,
27 | "..",
28 | "..",
29 | "HelloWalletContract.js",
30 | )
31 | deleteFiles([wrappedJs])
32 |
33 | const terminal = new StringTerminal()
34 | await runCommand(terminal, "js wrap", {
35 | file: path.resolve(__dirname, "..", "..", "HelloWallet.abi.json"),
36 | })
37 | expect(terminal.stderr.trim()).toEqual("")
38 |
39 | const { HelloWalletContract } = await import(wrappedJs)
40 | expect(typeof HelloWalletContract).toEqual("object")
41 |
42 | deleteFiles([wrappedJs])
43 | })
44 | */
45 |
--------------------------------------------------------------------------------
/src/controllers/clang/components.ts:
--------------------------------------------------------------------------------
1 | import * as os from "os"
2 | import { Component } from "../../core"
3 |
4 | const p = os.platform()
5 | let innerPath: string
6 | let targetName: string
7 | let ext: string
8 |
9 | if (p === "linux") {
10 | innerPath = "opt/work/llvm/install/bin/clang"
11 | targetName = "clang.tar"
12 | ext = p + ".tar.gz"
13 | } else if (p === "darwin") {
14 | innerPath = "bin/clang"
15 | targetName = "clang.zip"
16 | ext = p + ".zip"
17 | } else {
18 | innerPath = "bin/clang.exe"
19 | targetName = "clang.zip"
20 | ext = p + ".zip"
21 | }
22 |
23 | const TOOL_FOLDER_NAME = "clang"
24 |
25 | export const components = {
26 | compiler: new (class extends Component {
27 | getSourceName(version: string): string {
28 | return `${this.name}/${this.name}-${version
29 | .split(".")
30 | .join("_")}-${ext}`
31 | }
32 |
33 | async resolveVersion(downloadedVersion: string): Promise {
34 | return downloadedVersion
35 | }
36 | })(TOOL_FOLDER_NAME, "clang-for-tvm", {
37 | targetName,
38 | innerPath,
39 | isExecutable: true,
40 | }),
41 | }
42 |
--------------------------------------------------------------------------------
/src/controllers/clang/index.ts:
--------------------------------------------------------------------------------
1 | import { Command, Component, Terminal, ToolController } from "../../core"
2 | import path from "path"
3 | import { changeExt, uniqueFilePath, writeTextFile } from "../../core/utils"
4 | import fs from "fs"
5 | import { BasicContractCode, BasicContractHeaders } from "./snippets"
6 | import { components } from "./components"
7 |
8 | export const clangVersionCommand: Command = {
9 | name: "version",
10 | title: "Show C++ Compiler Version",
11 | async run(terminal: Terminal): Promise {
12 | terminal.log(await Component.getInfoAll(components))
13 | },
14 | }
15 |
16 | export const clangCreateCommand: Command = {
17 | name: "create",
18 | title: "Create C++ Contract",
19 | args: [
20 | {
21 | isArg: true,
22 | name: "name",
23 | title: "Contract Name",
24 | type: "string",
25 | defaultValue: "Contract",
26 | },
27 | {
28 | name: "folder",
29 | type: "folder",
30 | title: "Target folder (should exist, current by default)",
31 | },
32 | ],
33 | async run(terminal: Terminal, args: { name: string; folder: string }) {
34 | // filename was entered with an extension, delete it
35 | args.name = args.name.replace(/.cpp$/, "")
36 |
37 | const hFilePath = uniqueFilePath(args.folder, `${args.name}{}.hpp`)
38 | const cFilePath = uniqueFilePath(args.folder, `${args.name}{}.cpp`)
39 |
40 | writeTextFile(hFilePath, BasicContractHeaders)
41 | writeTextFile(
42 | cFilePath,
43 | BasicContractCode.split("{name}").join(hFilePath),
44 | )
45 | terminal.log(`${hFilePath} created.`)
46 | terminal.log(`${cFilePath} created.`)
47 | },
48 | }
49 |
50 | export const clangCompileCommand: Command = {
51 | name: "compile",
52 | title: "Compile C++ Contract",
53 | args: [
54 | {
55 | isArg: true,
56 | name: "file",
57 | type: "file",
58 | title: "Source file",
59 | nameRegExp: /\.cpp$/i,
60 | greedy: true,
61 | },
62 | ],
63 | async run(terminal: Terminal, args: { file: string }): Promise {
64 | for (let file of args.file.split(" ")) {
65 | const ext = path.extname(file)
66 | if (ext !== ".cpp") {
67 | terminal.log(`Choose source file.`)
68 | return
69 | }
70 | await Component.ensureInstalledAll(terminal, components)
71 | file = path.resolve(file)
72 | const tvcName = changeExt(file, ".tvc")
73 | const generatedAbiName = changeExt(file, ".abi")
74 | const renamedAbiName = changeExt(file, ".abi.json")
75 | await components.compiler.run(
76 | terminal,
77 | path.dirname(file), // cd to this directory
78 | [file, "-o", tvcName],
79 | )
80 |
81 | fs.renameSync(generatedAbiName, renamedAbiName)
82 | terminal.log(
83 | `Success, files created: ${tvcName}, ${renamedAbiName}`,
84 | )
85 | }
86 | },
87 | }
88 |
89 | export const clangUpdateCommand: Command = {
90 | name: "update",
91 | title: "Update C++ Compiler",
92 | args: [
93 | {
94 | name: "force",
95 | alias: "f",
96 | title: "Force reinstall even if up to date",
97 | type: "boolean",
98 | defaultValue: "false",
99 | },
100 | ],
101 | async run(terminal: Terminal, args: { force: boolean }): Promise {
102 | await Component.updateAll(terminal, args.force, components)
103 | },
104 | }
105 |
106 | export const clangSetCommand: Command = {
107 | name: "set",
108 | title: "Change C++ Compiler Config",
109 | args: [
110 | {
111 | name: "compiler",
112 | alias: "c",
113 | title: "Compiler version (version number or `latest`)",
114 | type: "string",
115 | defaultValue: "",
116 | },
117 | {
118 | name: "force",
119 | alias: "f",
120 | title: "Force reinstall even if up to date",
121 | type: "boolean",
122 | defaultValue: "false",
123 | },
124 | ],
125 | async run(
126 | terminal: Terminal,
127 | args: {
128 | force: boolean
129 | compiler: string
130 | },
131 | ): Promise {
132 | const versions: {
133 | compiler?: string
134 | } = {}
135 | if (args.compiler !== "") {
136 | versions.compiler = args.compiler
137 | }
138 | await Component.setVersions(terminal, args.force, components, versions)
139 | },
140 | }
141 |
142 | export const Clang: ToolController = {
143 | name: "clang",
144 | title: "C++ compiler",
145 | commands: [
146 | clangCreateCommand,
147 | clangCompileCommand,
148 | clangVersionCommand,
149 | clangSetCommand,
150 | clangUpdateCommand,
151 | ],
152 | }
153 |
--------------------------------------------------------------------------------
/src/controllers/clang/snippets.ts:
--------------------------------------------------------------------------------
1 | const header = `
2 | /**
3 | * This file was generated by EverDev.
4 | * EverDev is a part of EVER OS (see https://everos.dev).
5 | */
6 | `
7 | export const BasicContractCode =
8 | header +
9 | `
10 | #include "{name}"
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | using namespace tvm;
18 | using namespace schema;
19 |
20 | static constexpr unsigned TIMESTAMP_DELAY = 1800;
21 |
22 | class Proxy final : public smart_interface, public DProxy {
23 | using replay_protection_t = replay_attack_protection::timestamp;
24 | using data = DProxy;
25 | public:
26 | struct error_code : tvm::error_code {
27 | static constexpr unsigned message_sender_is_not_my_owner = 100;
28 | };
29 |
30 | __always_inline
31 | void constructor(uint256 pubkey) {
32 | owner_ = pubkey;
33 | }
34 |
35 | __always_inline
36 | void sendMessage(cell msg, uint8 flags) {
37 | require(msg_pubkey() == owner_, error_code::message_sender_is_not_my_owner);
38 | tvm_accept();
39 | tvm_sendmsg(msg, flags.get());
40 | }
41 | // =============== Support functions ==================
42 | DEFAULT_SUPPORT_FUNCTIONS(IProxy, replay_protection_t)
43 |
44 | // default processing of unknown messages
45 | __always_inline static int _fallback(cell msg, slice msg_body) {
46 | return 0;
47 | }
48 | };
49 |
50 | DEFINE_JSON_ABI(IProxy, DProxy, EProxy);
51 |
52 | // ----------------------------- Main entry functions ---------------------- //
53 | DEFAULT_MAIN_ENTRY_FUNCTIONS(Proxy, IProxy, DProxy, TIMESTAMP_DELAY)
54 | `
55 | export const BasicContractHeaders =
56 | header +
57 | `
58 | #pragma once
59 |
60 | #include
61 | #include
62 | #include
63 |
64 | namespace tvm { inline namespace schema {
65 |
66 | __interface IProxy {
67 |
68 | [[external, dyn_chain_parse]]
69 | void constructor(uint256 pubkey) = 1;
70 |
71 | [[external, noaccept, dyn_chain_parse]]
72 | void sendMessage(cell msg, uint8 flags) = 2;
73 | };
74 | using IProxyPtr = handle;
75 |
76 | struct DProxy {
77 | uint256 owner_;
78 | };
79 |
80 | __interface EProxy {
81 | };
82 |
83 | }} // namespace tvm::schema
84 | `
85 |
--------------------------------------------------------------------------------
/src/controllers/contract/accounts.ts:
--------------------------------------------------------------------------------
1 | import { Terminal } from "../../core"
2 | import { Account, AccountOptions, AccountType } from "@eversdk/appkit"
3 | import { NetworkRegistry } from "../network/registry"
4 | import { TonClient } from "@eversdk/core"
5 | import { SignerRegistry } from "../signer/registry"
6 | import { ParamParser } from "./param-parser"
7 | import { resolveContract } from "../../core/solFileResolvers"
8 |
9 | // Remove suffix graphql if exists and add projectId
10 | // Intentionally do not use URL object or any modules,
11 | // because url may lack `http://` prefix
12 | export const transformEndpoint = (project?: string) => (url: string) => {
13 | const result = url
14 | .trim()
15 | .replace(/\/graphql\/?$/i, "")
16 | .replace(/\/$/, "")
17 | return project ? `${result}/${project}` : result
18 | }
19 |
20 | export async function getAccount(
21 | terminal: Terminal,
22 | args: {
23 | file: string
24 | network: string
25 | signer: string
26 | data: string
27 | address?: string
28 | workchain?: string
29 | },
30 | ): Promise {
31 | const address = args.address ?? ""
32 | const abiConfig =
33 | address === "" && args.workchain
34 | ? {
35 | abi: {
36 | workchain: parseInt(args.workchain) || 0,
37 | },
38 | }
39 | : {}
40 | const network = new NetworkRegistry().get(args.network)
41 | const { project, accessKey } = network.credentials || {}
42 | const client = new TonClient({
43 | network: {
44 | endpoints: network.endpoints.map(transformEndpoint(project)),
45 |
46 | ...(accessKey ? { access_key: accessKey } : {}),
47 | },
48 | ...abiConfig,
49 | })
50 | const contract =
51 | args.file !== ""
52 | ? resolveContract(args.file)
53 | : { package: { abi: {} }, abiPath: "" }
54 | const signers = new SignerRegistry()
55 | const signerItem = await signers.resolveItem(args.signer, {
56 | useNoneForEmptyName: address !== "",
57 | })
58 | const options: AccountOptions = {
59 | signer: await signers.createSigner(signerItem),
60 | client,
61 | }
62 | const abiData = contract.package.abi.data ?? []
63 | if (abiData.length > 0 && args.data !== "") {
64 | options.initData = ParamParser.components(
65 | {
66 | name: "data",
67 | type: "tuple",
68 | components: abiData,
69 | },
70 | args.data,
71 | )
72 | }
73 | if (address !== "") {
74 | options.address = address
75 | }
76 | const account = new Account(contract.package, options)
77 | terminal.log("\nConfiguration\n")
78 | terminal.log(
79 | ` Network: ${network.name} (${NetworkRegistry.getEndpointsSummary(
80 | network,
81 | )})`,
82 | )
83 | terminal.log(
84 | ` Signer: ${
85 | signerItem
86 | ? `${signerItem.name} (public ${signerItem.keys.public})`
87 | : "None"
88 | }\n`,
89 | )
90 | if (address === "" && abiData.length > 0 && !options.initData) {
91 | terminal.log(
92 | `Address: Can't calculate address: additional deploying data required.`,
93 | )
94 | } else {
95 | terminal.log(
96 | `Address: ${await account.getAddress()}${
97 | address === "" ? " (calculated from TVC and signer public)" : ""
98 | }`,
99 | )
100 | }
101 | return account
102 | }
103 |
104 | export type ParsedAccount = {
105 | acc_type: AccountType
106 | code_hash?: string
107 | [name: string]: unknown
108 | }
109 |
110 | export async function getParsedAccount(
111 | account: Account,
112 | ): Promise {
113 | try {
114 | return await account.getAccount()
115 | } catch (err) {
116 | const acc = await account.client.net.query_collection({
117 | collection: "accounts",
118 | filter: { id: { eq: await account.getAddress() } },
119 | result: "acc_type",
120 | limit: 1,
121 | })
122 | if (acc.result.length === 0) {
123 | return {
124 | acc_type: AccountType.nonExist,
125 | }
126 | }
127 | throw err
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/controllers/contract/param-parser.ts:
--------------------------------------------------------------------------------
1 | import { AbiParam } from "@eversdk/core"
2 | import path from "path"
3 | import process from "process"
4 | import { loadJSON } from "../../core/utils"
5 |
6 | export class ParamParser {
7 | pos = 0
8 |
9 | private constructor(public text: string) {}
10 |
11 | static scalar(param: AbiParam, text: string): any {
12 | const parser = new ParamParser(text)
13 |
14 | return parser.parseScalar(param)
15 | }
16 |
17 | static components(param: AbiParam, text: string): any {
18 | const parser = new ParamParser(text)
19 |
20 | return parser.parseComponents(param)
21 | }
22 |
23 | hasMore() {
24 | return this.pos < this.text.length
25 | }
26 |
27 | nextIs(test: (c: string) => boolean): boolean {
28 | return this.hasMore() && test(this.text[this.pos])
29 | }
30 |
31 | passIf(test: (c: string) => boolean): boolean {
32 | if (this.nextIs(test)) {
33 | this.pos += 1
34 | return true
35 | }
36 | return false
37 | }
38 |
39 | pass(c: string): boolean {
40 | return this.passIf(x => x === c)
41 | }
42 |
43 | passWhile(test: (c: string) => boolean): string | undefined {
44 | const savePos = this.pos
45 |
46 | while (this.passIf(test)) {} /* eslint-disable-line no-empty */
47 | return this.pos > savePos
48 | ? this.text.substring(savePos, this.pos)
49 | : undefined
50 | }
51 |
52 | expectIf(
53 | test: (c: string) => boolean,
54 | param: AbiParam,
55 | expectMessage: string,
56 | ): string {
57 | const passed = this.passWhile(test)
58 |
59 | if (passed !== undefined) {
60 | return passed
61 | }
62 | throw this.error(
63 | `Param ${param.name} (${param.type}) expect ${expectMessage}`,
64 | )
65 | }
66 |
67 | expect(test: string, param: AbiParam): string {
68 | return this.expectIf(x => x === test, param, `"${test}"`)
69 | }
70 |
71 | parseScalar(param: AbiParam): any {
72 | const isScalarChar = (x: string) =>
73 | x !== "," && x !== ":" && x !== "[" && x !== "]"
74 | let quote = ""
75 |
76 | if (this.pass('"')) {
77 | quote = '"'
78 | } else if (this.pass("'")) {
79 | quote = "'"
80 | }
81 | if (quote !== "") {
82 | const value = this.passWhile(x => x !== quote) ?? ""
83 | this.expect(quote, param)
84 | return value
85 | }
86 | if (!this.nextIs(isScalarChar)) {
87 | return ""
88 | }
89 | return this.expectIf(isScalarChar, param, "value")
90 | }
91 |
92 | parseArray(param: AbiParam): any[] {
93 | const item = JSON.parse(JSON.stringify(param)) as AbiParam
94 | const value = []
95 |
96 | item.type = param.type.slice(0, -2)
97 | this.expect("[", param)
98 | while (!this.pass("]")) {
99 | value.push(this.parseParam(item))
100 | this.pass(",")
101 | }
102 | return value
103 | }
104 |
105 | parseParam(param: AbiParam): any {
106 | if (param.type.endsWith("[]")) {
107 | return this.parseArray(param)
108 | } else {
109 | return this.parseScalar(param)
110 | }
111 | }
112 |
113 | parseComponents(param: AbiParam): { [name: string]: any } {
114 | const text = this.text.trim()
115 | if (text.startsWith("@")) {
116 | return loadJSON(path.resolve(process.cwd(), text.substring(1)))
117 | }
118 |
119 | if (text.startsWith("{") && text.endsWith("}")) {
120 | try {
121 | return JSON.parse(text)
122 | } catch (err: any) {
123 | throw new Error(`Malformed JSON object has been passed`)
124 | }
125 | }
126 |
127 | const isLetter = (x: string) => x.toLowerCase() !== x.toUpperCase()
128 | const isDigit = (x: string) => x >= "0" && x <= "9"
129 | const isIdent = (x: string) => isLetter(x) || isDigit(x) || x === "_"
130 | const components = param.components ?? []
131 | const value: { [name: string]: any } = {}
132 |
133 | while (this.hasMore()) {
134 | const name = this.expectIf(isIdent, param, "name")
135 | this.expect(":", param)
136 | const component = components.find(
137 | x => x.name.toLowerCase() === name.toLowerCase(),
138 | )
139 | if (!component) {
140 | throw this.error(`Unknown field ${name}`)
141 | }
142 | if (param.name in value) {
143 | throw new Error(`Field "${name}" already defined.`)
144 | }
145 | value[name] = this.parseParam(component)
146 | if (this.hasMore()) {
147 | this.expect(",", param)
148 | }
149 | }
150 | return value
151 | }
152 |
153 | private error(message: string) {
154 | const text = this.text
155 | const pos = this.pos
156 | const start = Math.max(pos - 12, 0)
157 | const end = Math.min(pos + 12, text.length)
158 | const prefix = start > 0 ? "..." : ""
159 | const suffix = end < text.length ? "..." : ""
160 | const context = `"${prefix}${text.substring(
161 | start,
162 | pos,
163 | )} -> ${text.substring(pos, end)}${suffix}"`
164 |
165 | return new Error(`${message} at ${context}`)
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/controllers/contract/run.ts:
--------------------------------------------------------------------------------
1 | import { Terminal } from "../../core"
2 | import {
3 | AbiFunction,
4 | AbiParam,
5 | DecodedMessageBody,
6 | DecodedOutput,
7 | MessageBodyType,
8 | Signer,
9 | } from "@eversdk/core"
10 | import { Account } from "@eversdk/appkit"
11 | import { ParamParser } from "./param-parser"
12 | import { SignerRegistry } from "../signer/registry"
13 | import * as process from "process"
14 |
15 | export async function resolveFunction(
16 | terminal: Terminal,
17 | account: Account,
18 | functionName: string,
19 | preventUi: boolean,
20 | ): Promise {
21 | const functions = (account.contract.abi.functions ?? []).filter(
22 | fn => fn.name !== "constructor",
23 | )
24 | functionName = functionName.trim()
25 | while (functionName === "" && !preventUi) {
26 | terminal.log("\nAvailable functions:\n")
27 | functions.forEach((x, i) => terminal.log(` ${i + 1}) ${x.name}`))
28 | terminal.log()
29 |
30 | const functionIndex =
31 | Number.parseInt(
32 | await inputParam(terminal, {
33 | name: "Select function",
34 | type: "number",
35 | }),
36 | ) - 1
37 | if (functionIndex >= 0 && functionIndex < functions.length) {
38 | return functions[functionIndex]
39 | }
40 | terminal.log("Invalid function number. Try again.")
41 | }
42 | if (functionName === "") {
43 | throw new Error("Function name isn't specified")
44 | }
45 | const func = account.contract.abi.functions?.find(
46 | x => x.name === functionName,
47 | )
48 | if (!func) {
49 | throw new Error(`Function not found: ${functionName}`)
50 | }
51 | return func
52 | }
53 |
54 | function inputLine(terminal: Terminal, prompt: string): Promise {
55 | terminal.write(` ${prompt}: `)
56 | return new Promise(resolve => {
57 | const standard_input = process.stdin
58 | standard_input.setEncoding("utf-8")
59 | // SO: https://stackoverflow.com/questions/54182732/process-never-ends-when-using-process-stdin-once
60 | standard_input.resume()
61 | standard_input.once("data", function (data) {
62 | standard_input.pause()
63 | resolve(`${data}`.trim())
64 | })
65 | })
66 | }
67 |
68 | async function inputTuple(terminal: Terminal, param: AbiParam): Promise {
69 | for (;;) {
70 | const value = await inputLine(terminal, `${param.name} (${param.type})`)
71 | try {
72 | return JSON.parse(value)
73 | } catch (err: any) {
74 | terminal.log(err.toString())
75 | }
76 | }
77 | }
78 |
79 | async function inputScalar(terminal: Terminal, param: AbiParam): Promise {
80 | for (;;) {
81 | const value = await inputLine(terminal, `${param.name} (${param.type})`)
82 | try {
83 | return ParamParser.scalar(param, `"${value}"`)
84 | } catch (err: any) {
85 | terminal.log(err.toString())
86 | }
87 | }
88 | }
89 |
90 | async function inputArray(terminal: Terminal, param: AbiParam): Promise {
91 | const item = JSON.parse(JSON.stringify(param)) as AbiParam
92 | item.type = param.type.slice(0, -2)
93 | const count = Number(
94 | await inputLine(terminal, `Enter number of items in ${param.name}`),
95 | )
96 | const items = []
97 | let i = 1
98 | while (i <= count) {
99 | item.name = `${param.name} ${i}`
100 | items.push(await inputParam(terminal, item))
101 | i += 1
102 | }
103 | return items
104 | }
105 |
106 | async function inputParam(terminal: Terminal, param: AbiParam): Promise {
107 | if (param.type.endsWith("[]")) {
108 | return inputArray(terminal, param)
109 | } else if (param.type.endsWith("tuple")) {
110 | return inputTuple(terminal, param)
111 | } else {
112 | return inputScalar(terminal, param)
113 | }
114 | }
115 |
116 | export async function resolveParams(
117 | terminal: Terminal,
118 | prompt: string,
119 | params: AbiParam[],
120 | paramsString: string,
121 | preventUi: boolean,
122 | ): Promise