├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitattributes
├── .github
├── pull_request_template.md
└── workflows
│ ├── changelog.yml
│ ├── core-ci-checks.yml
│ ├── main.yml
│ ├── pr-checks.yml
│ └── publish.yml
├── .gitignore
├── .husky
├── commit-msg
└── pre-commit
├── .mocharc.js
├── .nvmrc
├── .prettierignore
├── .prettierrc.json
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── .vscodeignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── GitVersion.yml
├── LICENSE
├── PRIVACY.md
├── README.md
├── commitlint.config.js
├── coverconfig.json
├── images
├── GanacheLogo.png
├── GitLogo.png
├── NodeLogo.png
├── NpmLogo.png
├── OpenWelcomePage.jpg
├── OpenZLogo.png
├── PythonLogo.png
├── TruffleLogo.png
├── TruffleLogo.svg
├── blockchain-service-logo.png
├── buildContracts.png
├── consensys-logo.png
├── createProject.png
├── createService.png
├── dashboard-log.png
├── deployContracts.png
├── deployContractsRightClick.png
├── ganache-log.png
├── ide-debugging.png
├── newProjectDir.png
├── truffle-log.png
├── truffle.svg
└── walkthrough
│ ├── ganache-actions-menu.png
│ ├── networks-view-infura.png
│ └── new-solidity-project.gif
├── package.json
├── polyfills
└── original-require.js
├── resources
├── codeFlowResult
│ ├── index.html
│ └── main.css
├── dark
│ ├── ABNetwork.svg
│ ├── ABS-consortium.svg
│ ├── ABS-member.svg
│ ├── ABS-service.svg
│ ├── BlockchainDataManager-service_and_project.svg
│ ├── BlockchainDataManagerApplication.svg
│ ├── BlockchainDataManagerGroupInput.svg
│ ├── BlockchainDataManagerGroupOutput.svg
│ ├── BlockchainDataManagerOutput.svg
│ ├── DashboardService.svg
│ ├── EthereumNetwork.svg
│ ├── GenericService.svg
│ ├── InfuraLayer.svg
│ ├── InfuraProject.svg
│ ├── InfuraService.svg
│ ├── IpfsNetwork.svg
│ ├── LocalNetwork.svg
│ ├── LocalProject.svg
│ ├── LocalService.svg
│ └── dependency.svg
├── ganache
│ ├── assets
│ │ ├── fonts
│ │ │ ├── FiraCode-Regular.ttf
│ │ │ ├── FiraSans-Regular.ttf
│ │ │ ├── RobotoCondensed-Bold.ttf
│ │ │ └── RobotoCondensed-Regular.ttf
│ │ └── icons
│ │ │ ├── account.svg
│ │ │ ├── blocks.svg
│ │ │ ├── contract.svg
│ │ │ ├── events.svg
│ │ │ └── transactions.svg
│ ├── index.html
│ ├── main.css
│ └── main.js
├── light
│ ├── ABNetwork.svg
│ ├── ABS-consortium.svg
│ ├── ABS-member.svg
│ ├── ABS-service.svg
│ ├── BlockchainDataManager-service_and_project.svg
│ ├── BlockchainDataManagerApplication.svg
│ ├── BlockchainDataManagerGroupInput.svg
│ ├── BlockchainDataManagerGroupOutput.svg
│ ├── BlockchainDataManagerOutput.svg
│ ├── DashboardService.svg
│ ├── EthereumNetwork.svg
│ ├── GenericService.svg
│ ├── InfuraLayer.svg
│ ├── InfuraProject.svg
│ ├── InfuraService.svg
│ ├── IpfsNetwork.svg
│ ├── LocalNetwork.svg
│ ├── LocalProject.svg
│ ├── LocalService.svg
│ └── dependency.svg
├── logPanel
│ ├── index.html
│ ├── main.css
│ └── main.js
├── walkthrough
│ ├── connect-ganache.md
│ ├── create-project.md
│ ├── debug-transactions.md
│ ├── deploy-contracts.png
│ ├── explore-commands.png
│ ├── infura-sign-in.md
│ └── resources.md
└── welcome
│ ├── changelog.html
│ ├── main.css
│ ├── main.js
│ └── prereqs.html
├── src
├── Constants.ts
├── Models
│ ├── CancellationEvent.ts
│ ├── EnumStorage.ts
│ ├── IDeployDestination.ts
│ ├── ItemCreators
│ │ ├── CommandItemCreator.ts
│ │ ├── GenericNetworkNodeItemCreator.ts
│ │ ├── GenericProjectItemCreator.ts
│ │ ├── GenericServiceItemCreator.ts
│ │ ├── InfuraLayerItemCreator.ts
│ │ ├── InfuraNetworkNodeItemCreator.ts
│ │ ├── InfuraProjectItemCreator.ts
│ │ ├── InfuraServiceItemCreator.ts
│ │ ├── ItemCreator.ts
│ │ ├── LocalNetworkNodeItemCreator.ts
│ │ ├── LocalProjectItemCreator.ts
│ │ ├── LocalServiceItemCreator.ts
│ │ ├── NetworkNodeItemCreator.ts
│ │ └── NullableItemCreator.ts
│ ├── ItemFactory.ts
│ ├── ItemType.ts
│ ├── QuickPickItems
│ │ ├── InfuraProjectItem.ts
│ │ └── NetworkForContractItem.ts
│ ├── StatusBarItems
│ │ └── Contract.ts
│ └── TreeItems
│ │ ├── Command.ts
│ │ ├── ExtensionItem.ts
│ │ ├── GenericNetworkNode.ts
│ │ ├── GenericProject.ts
│ │ ├── GenericService.ts
│ │ ├── Group.ts
│ │ ├── IExtensionItem.ts
│ │ ├── InfuraLayer.ts
│ │ ├── InfuraNetworkNode.ts
│ │ ├── InfuraProject.ts
│ │ ├── InfuraService.ts
│ │ ├── Layer.ts
│ │ ├── LocalNetworkNode.ts
│ │ ├── LocalProject.ts
│ │ ├── LocalService.ts
│ │ ├── MnemonicNetworkNode.ts
│ │ ├── NetworkNode.ts
│ │ ├── Nullable.ts
│ │ ├── Project.ts
│ │ └── Service.ts
├── Output.ts
├── Telemetry.ts
├── commands
│ ├── ContractCommands.ts
│ ├── DashboardCommands.ts
│ ├── DebuggerCommands.ts
│ ├── GanacheCommands.ts
│ ├── GenericCommands.ts
│ ├── InfuraCommands.ts
│ ├── ProjectCommands.ts
│ ├── SdkCoreCommands.ts
│ ├── ServiceCommands.ts
│ └── TruffleCommands.ts
├── debugAdapter
│ ├── cmdCommandExecutor.ts
│ ├── configuration
│ │ ├── debugAdapterDescriptorFactory.ts
│ │ ├── debugConfigurationProvider.ts
│ │ └── debuggerConfiguration.ts
│ ├── constants
│ │ ├── debugAdapter.ts
│ │ └── debugSessionCommands.ts
│ ├── contracts
│ │ ├── contractHelpers.ts
│ │ └── contractJsonsProvider.ts
│ ├── debugAdapterTracker
│ │ ├── debugAdapterTracker.ts
│ │ └── debugAdapterTrackerFactory.ts
│ ├── debugNetwork.ts
│ ├── debugSession.ts
│ ├── helpers.ts
│ ├── instructionsView
│ │ ├── instructionDataManager.ts
│ │ ├── instructionDataProvider.ts
│ │ ├── instructionTreeNode.ts
│ │ └── instructionView.ts
│ ├── models
│ │ ├── ICallInfo.ts
│ │ ├── IContractJsonModel.ts
│ │ ├── IExpressionEval.ts
│ │ ├── IInstruction.ts
│ │ ├── ITransactionInputData.ts
│ │ ├── ITransactionResponse.ts
│ │ └── debuggerTypes.ts
│ ├── runtimeInterface.ts
│ ├── transaction
│ │ ├── transactionInputDataDecoder.ts
│ │ └── transactionProvider.ts
│ ├── types
│ │ ├── @truffle
│ │ │ ├── debugger.d.ts
│ │ │ ├── environment.d.ts
│ │ │ ├── provider.d.ts
│ │ │ └── workflow-compile.d.ts
│ │ ├── abi-decoder.d.ts
│ │ └── web3.d.ts
│ ├── variablesHandler.ts
│ └── web3Wrapper.ts
├── extension.ts
├── functions
│ └── explorer.ts
├── helpers
│ ├── ConfigurationReader.ts
│ ├── TruffleConfiguration.ts
│ ├── checkTruffleConfigTemplate.js
│ ├── command.ts
│ ├── debugConfigurationReader.ts
│ ├── enumExtractor.ts
│ ├── git.ts
│ ├── required.ts
│ ├── shell.ts
│ ├── uriHandlerController.ts
│ ├── userInteraction.ts
│ ├── userSettings.ts
│ ├── vscodeEnvironment.ts
│ └── workspace.ts
├── pages
│ ├── BasicWebView.ts
│ ├── Changelog.ts
│ ├── GanacheDetails.ts
│ └── Requirements.ts
├── resourceExplorers
│ ├── GenericResourceExplorer.ts
│ ├── InfuraResourceExplorer.ts
│ └── LocalResourceExplorer.ts
├── services
│ ├── HttpService.ts
│ ├── MnemonicRepository.ts
│ ├── NetworkService.ts
│ ├── contract
│ │ ├── AbstractAdapter.ts
│ │ ├── Contract.ts
│ │ ├── ContractDB.ts
│ │ ├── ContractInstance.ts
│ │ ├── ContractInstanceWithMetadata.ts
│ │ ├── ContractService.ts
│ │ ├── InMemoryAdapter.ts
│ │ ├── Network.ts
│ │ ├── Provider.ts
│ │ └── TruffleDBAdapter.ts
│ ├── dashboard
│ │ ├── DashboardService.ts
│ │ └── DashboardServiceClient.ts
│ ├── extensionAdapter
│ │ ├── IExtensionAdapter.ts
│ │ ├── TruffleExtensionAdapter.ts
│ │ └── index.ts
│ ├── ganache
│ │ ├── GanacheService.ts
│ │ └── GanacheServiceClient.ts
│ ├── generic
│ │ ├── GenericService.ts
│ │ └── GenericServiceClient.ts
│ ├── infuraService
│ │ ├── InfuraDto
│ │ │ ├── ICreateProjectRequestDto.ts
│ │ │ ├── IInfuraEndpointDto.ts
│ │ │ ├── IInfuraProjectDto.ts
│ │ │ ├── IInfuraProjectQuickPick.ts
│ │ │ ├── IInfuraUserDto.ts
│ │ │ ├── IProjectsResultDto.ts
│ │ │ └── index.ts
│ │ ├── InfuraServiceClient.ts
│ │ └── codeFlowLogin.ts
│ └── tree
│ │ └── TreeManager.ts
├── validators
│ ├── DialogResultValidator.ts
│ ├── UrlValidator.ts
│ └── validator.ts
└── views
│ ├── ContractExplorerView.ts
│ ├── DashboardView.ts
│ ├── DeploymentsView.ts
│ ├── HelpView.ts
│ ├── LogView.ts
│ ├── NetworksView.ts
│ └── lib
│ └── OpenUrlTreeItem.ts
├── test
├── ContractInstanceWithMetadata.test.ts
├── FakeExtensionState.ts
├── MnemonicRepository.test.ts
├── TestConstants.ts
├── TreeManager.test.ts
├── TruffleCommandsTests
│ ├── WriteToBuffer.test.ts
│ ├── buildContracts.test.ts
│ ├── deployContracts.test.ts
│ ├── telemetry.test.ts
│ └── testData
│ │ ├── TestContract.json
│ │ └── truffle-config.js
├── TruffleConfig.test.ts
├── TruffleExtensionAdapter.test.ts
├── commands.test.ts
├── commands
│ ├── DashboardCommands.test.ts
│ ├── DashboardService.test.ts
│ ├── DebuggerCommands.test.ts
│ ├── GanacheCommands.int.test.ts
│ ├── GanacheCommands.test.ts
│ ├── GanacheService.test.ts
│ ├── ProjectCommand.test.ts
│ └── ServiceCommands
│ │ ├── connectService.integration.test.ts
│ │ ├── connectService.test.ts
│ │ ├── createService.test.ts
│ │ ├── disconnecNetwork.test.ts
│ │ └── telemetry.test.ts
├── debugAdapter
│ ├── SolidityDebugSessionClient.ts
│ ├── debugSession.test.ts
│ ├── helper.test.ts
│ ├── runtimeInterface.test.ts
│ ├── variablesHandler.test.ts
│ └── web3Wrapper.test.ts
├── index.ts
├── required.test.ts
├── runTest.ts
├── testData
│ ├── enumTestContract.json
│ ├── enumTestContract.sol
│ ├── referenceAstObject.json
│ └── truffleConfigTestdata.ts
├── testHelpers
│ └── Random.ts
├── userInteraction.test.ts
├── validators
│ ├── DialogResultValidator.test.ts
│ ├── UrlValidator.test.ts
│ ├── test-dialog-answers.ts
│ └── validator.test.ts
├── vscode-register.ts
├── vscode.ts
└── workspace.test.ts
├── tsconfig.json
├── webpack.common.js
├── webpack.dev.js
├── webpack.prod.js
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | tab_width = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 | max_line_length = 120
12 |
13 | [*.html]
14 | indent_size = 4
15 | tab_width = 4
16 | max_line_length = off
17 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | ### JetBrains template
2 | .idea/
3 |
4 | ### Common
5 | out/
6 | coverage/
7 |
8 | ### Node template
9 | package-lock.json
10 |
11 | ### Logs
12 | logs
13 | *.log
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 |
18 | # Dependency directories
19 | node_modules/
20 | jspm_packages/
21 |
22 | # dotenv environment variables file
23 | .env
24 |
25 | ### VisualStudioCode template
26 | .vscode/*
27 | !.vscode/settings.json
28 | !.vscode/tasks.json
29 | !.vscode/launch.json
30 | !.vscode/extensions.json
31 |
32 | .vscode-test/
33 | *.vsix
34 |
35 | ### User template
36 | resources/drizzle/
37 |
38 | ui-test/
39 |
40 | ### We ignore the config file to stop issues.
41 | # .eslintrc.js
42 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## PR description
2 |
3 |
4 |
5 | ## Documentation
6 |
7 | - [ ] I thought about documentation and added the `doc-change-required` label to this PR if documentation updates are required.
8 |
--------------------------------------------------------------------------------
/.github/workflows/changelog.yml:
--------------------------------------------------------------------------------
1 | name: Changelog Test
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | build:
8 | name: '✏️ Changelog generation'
9 | runs-on: ubuntu-18.04
10 | steps:
11 | - name: '📥 Check-out'
12 | uses: actions/checkout@v2
13 | # explicitly specify ${{ github.head_ref }} in the checkout Action.
14 | # This is required in order to work with the pull_request event (or any other non-push event).
15 | with:
16 | ref: ${{ github.head_ref }}
17 |
18 | - name: '✏️ Generate full changelog'
19 | id: generate-full-changelog
20 | # https://github.com/heinrichreimer/action-github-changelog-generator
21 | uses: heinrichreimer/github-changelog-generator-action@v2.3
22 | with:
23 | token: ${{ secrets.GITHUB_TOKEN }}
24 | headerLabel: '# 📑 Changelog'
25 | breakingLabel: '### 💥 Breaking'
26 | enhancementLabel: '### 🚀 Enhancements'
27 | bugsLabel: '### 🐛 Bug fixes'
28 | deprecatedLabel: '### ⚠️ Deprecations'
29 | removedLabel: '### 🔥 Removals'
30 | securityLabel: '### 🛡️ Security'
31 | issuesLabel: '### 📁 Other issues'
32 | prLabel: '### 📁 Other pull requests'
33 | addSections: '{"documentation":{"prefix":"### 📖 Documentation","labels":["documentation"]},"tests":{"prefix":"### ✅ Testing","labels":["tests"]}}'
34 | issues: true
35 | issuesWoLabels: true
36 | pullRequests: true
37 | prWoLabels: true
38 | author: true
39 | unreleased: true
40 | compareLink: true
41 | stripGeneratorNotice: true
42 | verbose: true
43 | - name: '🖨️ Print changelog to console'
44 | run: cat CHANGELOG.md
45 |
46 | # TODO - look at using autocommit here:
47 | # - name: Commit updated CHANGELOG
48 | # uses: stefanzweifel/git-auto-commit-action@v4
49 | # with:
50 | # branch: ${{ github.event.release.target_commitish }}
51 | # commit_message: Update CHANGELOG
52 | # commit_options: '--no-verify'
53 | # file_pattern: CHANGELOG.md
54 |
55 | - name: '📤 Upload changelog'
56 | uses: actions/upload-artifact@v1.0.0
57 | with:
58 | name: 'Changelog'
59 | path: CHANGELOG.md
60 |
--------------------------------------------------------------------------------
/.github/workflows/core-ci-checks.yml:
--------------------------------------------------------------------------------
1 | name: Core CI Checks
2 |
3 | on:
4 | workflow_call:
5 |
6 | jobs:
7 | core-checks:
8 | runs-on: windows-latest
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v3
12 |
13 | - name: Setup Node
14 | uses: actions/setup-node@v3
15 | with:
16 | node-version: lts/*
17 | cache: 'yarn'
18 |
19 | - name: Clean install dependencies. Fail on lockfile Changes.
20 | run: yarn install --immutable --immutable-cache --check-cache --non-interactive
21 |
22 | - name: Prettier
23 | run: yarn prettier
24 |
25 | - name: ESLint
26 | run: yarn eslint
27 |
28 | - name: Tests
29 | run: yarn test:int
30 |
31 | - name: Build smoke check package
32 | run: yarn package
33 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Main Branch Checks
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - master
8 | paths-ignore: # dont run when changes made to these folders
9 | - '.vscode/**'
10 |
11 | jobs:
12 | checks:
13 | name: Core Checks - Workflow Call
14 | uses: ./.github/workflows/core-ci-checks.yml
15 | secrets: inherit
16 |
--------------------------------------------------------------------------------
/.github/workflows/pr-checks.yml:
--------------------------------------------------------------------------------
1 | # PR Checks File for checking PR commits meet our requirements.
2 | name: PR Checks
3 |
4 | on:
5 | pull_request:
6 | branches:
7 | - master
8 | - develop
9 | jobs:
10 | pr-checks:
11 | name: Core CI Checks - Workflow Call
12 | uses: ./.github/workflows/core-ci-checks.yml
13 | secrets: inherit
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### DS store
2 | .DS_Store
3 |
4 | ### JetBrains template
5 | .idea/
6 |
7 | ### Common
8 | out/
9 | coverage/
10 |
11 | ### Node template
12 | package-lock.json
13 |
14 | ### Logs
15 | logs
16 | *.log
17 | npm-debug.log*
18 | yarn-debug.log*
19 | yarn-error.log*
20 |
21 | # Dependency directories
22 | node_modules/
23 | jspm_packages/
24 |
25 | # dotenv environment variables file
26 | .env
27 |
28 | ### VisualStudioCode template
29 | .vscode/*
30 | !.vscode/settings.json
31 | !.vscode/tasks.json
32 | !.vscode/launch.json
33 | !.vscode/extensions.json
34 |
35 | .vscode-test/
36 | *.vsix
37 |
38 | ### User template
39 | resources/drizzle/
40 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx --no -- commitlint --edit "$1"
5 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | # exit early if we are on a CI server.
3 | [ -n "$CI" ] && exit 0
4 |
5 | . "$(dirname -- "$0")/_/husky.sh"
6 |
7 | yarn test
8 | npx eslint src/* test/*
9 | npx pretty-quick --staged
10 |
--------------------------------------------------------------------------------
/.mocharc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This configuration[1] is used when `mocha` is invoked directly
3 | * from the command line.
4 | *
5 | * Note that this configuration does not affect tests
6 | * when they are executed through `runTests`.
7 | *
8 | * [1] https://mochajs.org/#configuring-mocha-nodejs
9 | */
10 | module.exports = {
11 | /**
12 | * From `mocha -h`
13 | *
14 | * ```txt
15 | * --require, -r Require module [array] [default: (none)]
16 | * ```
17 | */
18 | require: [
19 | // We use `ts-node/register`[1] to run our tests without compiling them.
20 | //
21 | // [1] https://typestrong.org/ts-node/docs/recipes/mocha/#mocha-7-and-newer.
22 | 'ts-node/register',
23 |
24 | // This option is used to provide a drop-in replacement for the `vscode` module.
25 | // When running `mocha` tests without a VS Code Development Extension Host[1],
26 | // the `vscode` module is not available, so we need to provide a test replacement.
27 | //
28 | // See `test/vscode-register.ts` for more details on how this is implemented.
29 | //
30 | // This answer[2]'s 'bonus track' section was used as a inspiration for this method,
31 | // to run code before the tests begin.
32 | //
33 | // [1] https://code.visualstudio.com/api/working-with-extensions/testing-extension
34 | // [2] https://stackoverflow.com/questions/10561598/global-before-and-beforeeach-for-mocha/51152004#51152004
35 | 'test/vscode-register.ts',
36 | ],
37 |
38 | /**
39 | * From `mocha -h`
40 | *
41 | * ```txt
42 | * spec One or more files, directories, or globs to test
43 | * [array] [default: ["test"]]
44 | * ```
45 | */
46 | spec: [
47 | // These are the same test files covered by the VS Code Host test runner.
48 | 'test/**/*.test.ts',
49 | ],
50 | };
51 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 16
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | ### JetBrains template
2 | .idea/
3 |
4 | ### Common
5 | out/
6 | coverage/
7 |
8 | ### Node template
9 | package-lock.json
10 |
11 | ### Logs
12 | logs
13 | *.log
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 |
18 | # Dependency directories
19 | node_modules/
20 | jspm_packages/
21 |
22 | # dotenv environment variables file
23 | .env
24 |
25 | ### VisualStudioCode template
26 | .vscode/*
27 | !.vscode/settings.json
28 | !.vscode/tasks.json
29 | !.vscode/launch.json
30 | !.vscode/extensions.json
31 |
32 | .vscode-test/
33 | *.vsix
34 |
35 | ### User template
36 | resources/drizzle/
37 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 2,
3 | "useTabs": false,
4 | "arrowParens": "always",
5 | "semi": true,
6 | "quoteProps": "as-needed",
7 | "singleQuote": true,
8 | "bracketSpacing": false
9 | }
10 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See http://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": ["dbaeumer.vscode-eslint"]
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "out": false // set this to true to hide the "out" folder with the compiled JS files
5 | },
6 | "search.exclude": {
7 | "out": true // set this to false to include "out" folder in search results
8 | },
9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts
10 | "typescript.tsc.autoDetect": "off",
11 | "cSpell.words": [
12 | "Truffle Service",
13 | "Blanco",
14 | "Bytecode",
15 | "Ethereum",
16 | "blockchain",
17 | "endregion",
18 | "infura",
19 | "microservices",
20 | "subfolder"
21 | ],
22 | "javascript.referencesCodeLens.enabled": true,
23 | "typescript.implementationsCodeLens.enabled": true,
24 | "typescript.referencesCodeLens.enabled": true
25 | }
26 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "Build extension",
6 | "type": "npm",
7 | "script": "compile",
8 | "presentation": {
9 | "reveal": "silent",
10 | "panel": "shared",
11 | "showReuseMessage": false
12 | },
13 | "group": "build"
14 | },
15 | {
16 | "label": "Clean tests folder",
17 | "type": "npm",
18 | "script": "clean",
19 | "presentation": {
20 | "reveal": "silent",
21 | "panel": "shared",
22 | "showReuseMessage": false
23 | },
24 | "group": "build"
25 | },
26 | {
27 | "label": "Build extension with watcher",
28 | "type": "npm",
29 | "script": "watch",
30 | "problemMatcher": "$tsc-watch",
31 | "isBackground": true,
32 | "presentation": {
33 | "reveal": "never"
34 | },
35 | "group": "build",
36 | "dependsOn": ["Clean tests folder"]
37 | },
38 | {
39 | "label": "Install dependencies for Drizzle UI",
40 | "type": "npm",
41 | "script": "install",
42 | "path": "drizzleUI/",
43 | "presentation": {
44 | "reveal": "silent",
45 | "panel": "shared",
46 | "showReuseMessage": false
47 | },
48 | "group": "build"
49 | },
50 | {
51 | "label": "Build Drizzle UI",
52 | "type": "npm",
53 | "script": "build:ext:dev",
54 | "path": "drizzleUI/",
55 | "presentation": {
56 | "reveal": "silent",
57 | "panel": "shared",
58 | "showReuseMessage": false
59 | },
60 | "group": "build"
61 | },
62 | {
63 | "label": "Run extension with Drizzle UI",
64 | "dependsOn": ["Install dependencies for Drizzle UI", "Build Drizzle UI", "Build extension"]
65 | },
66 | {
67 | "label": "Prepare resources for ui-tests",
68 | "type": "npm",
69 | "script": "prepare-ui-test",
70 | "path": "ui-test/",
71 | "presentation": {
72 | "reveal": "silent",
73 | "panel": "shared",
74 | "showReuseMessage": false
75 | },
76 | "group": "test"
77 | }
78 | ]
79 | }
80 |
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .github/**
2 | .idea/**
3 | .vscode/**
4 | .vscode-test/**
5 | coverage/**
6 | node_modules/**
7 | out/**
8 | !out/src/mscorlib.js
9 | !out/src/Nethereum.Generators.DuoCode.js
10 | !out/src/extension.js
11 | !out/src/debugger.js
12 | !out/src/checkTruffleConfigTemplate.js
13 | src/**
14 | test/**
15 | .editorconfig
16 | .gitignore
17 | .npmignore
18 | **/tsconfig.json
19 | **/tslint.json
20 | **/*.map
21 | **/*.ts
22 | **/webpack.*.js
23 | **/.mocharc.js
24 | **/coverconfig.json
25 | .husky/**
26 | **/GitVersion.yml
27 | **/commitlint.config.js
28 | **/.nvmrc
29 | **/.eslintignore
30 | **/.prettierignore
31 |
--------------------------------------------------------------------------------
/GitVersion.yml:
--------------------------------------------------------------------------------
1 | mode: ContinuousDeployment
2 | branches:
3 | develop:
4 | tag: PreRelease
5 | increment: Patch
6 | ignore:
7 | sha: []
8 | merge-message-formats: {}
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Truffle for VSCode
4 | Copyright (c) ConsenSys Software Inc. All rights reserved.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE
23 |
--------------------------------------------------------------------------------
/PRIVACY.md:
--------------------------------------------------------------------------------
1 | Data Collection. The software may collect information about you and your use of the software and send it to ConsenSys Software Inc.. ConsenSys Software Inc. may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and ConsenSys Software Inc. to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of ConsenSys Software Inc.'s privacy statement. Our privacy statement is located at [Privacy Policy](https://consensys.net/privacy-policy/). You can learn more about data collection and use in our privacy statement. Your use of the software operates as your consent to these practices.
2 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {extends: ['@commitlint/config-conventional']};
2 |
--------------------------------------------------------------------------------
/coverconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": true,
3 | "relativeSourcePath": "../src",
4 | "relativeCoverageDir": "../../coverage",
5 | "ignorePatterns": ["**/node_modules/**"],
6 | "includePid": false,
7 | "reports": ["html", "lcov", "text-summary"],
8 | "verbose": false
9 | }
10 |
--------------------------------------------------------------------------------
/images/GanacheLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/GanacheLogo.png
--------------------------------------------------------------------------------
/images/GitLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/GitLogo.png
--------------------------------------------------------------------------------
/images/NodeLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/NodeLogo.png
--------------------------------------------------------------------------------
/images/NpmLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/NpmLogo.png
--------------------------------------------------------------------------------
/images/OpenWelcomePage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/OpenWelcomePage.jpg
--------------------------------------------------------------------------------
/images/OpenZLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/OpenZLogo.png
--------------------------------------------------------------------------------
/images/PythonLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/PythonLogo.png
--------------------------------------------------------------------------------
/images/TruffleLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/TruffleLogo.png
--------------------------------------------------------------------------------
/images/TruffleLogo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/blockchain-service-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/blockchain-service-logo.png
--------------------------------------------------------------------------------
/images/buildContracts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/buildContracts.png
--------------------------------------------------------------------------------
/images/consensys-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/consensys-logo.png
--------------------------------------------------------------------------------
/images/createProject.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/createProject.png
--------------------------------------------------------------------------------
/images/createService.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/createService.png
--------------------------------------------------------------------------------
/images/dashboard-log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/dashboard-log.png
--------------------------------------------------------------------------------
/images/deployContracts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/deployContracts.png
--------------------------------------------------------------------------------
/images/deployContractsRightClick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/deployContractsRightClick.png
--------------------------------------------------------------------------------
/images/ganache-log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/ganache-log.png
--------------------------------------------------------------------------------
/images/ide-debugging.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/ide-debugging.png
--------------------------------------------------------------------------------
/images/newProjectDir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/newProjectDir.png
--------------------------------------------------------------------------------
/images/truffle-log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/truffle-log.png
--------------------------------------------------------------------------------
/images/truffle.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/images/walkthrough/ganache-actions-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/walkthrough/ganache-actions-menu.png
--------------------------------------------------------------------------------
/images/walkthrough/networks-view-infura.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/walkthrough/networks-view-infura.png
--------------------------------------------------------------------------------
/images/walkthrough/new-solidity-project.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/images/walkthrough/new-solidity-project.gif
--------------------------------------------------------------------------------
/polyfills/original-require.js:
--------------------------------------------------------------------------------
1 | module.exports = eval('require');
2 |
--------------------------------------------------------------------------------
/resources/codeFlowResult/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Infura Account - Sign In
7 |
8 |
9 |
10 |
11 |
12 | Visual Studio Code
13 |
14 |
15 |
You are signed in now and can close this page.
16 |
17 | An error occurred while signing in:
18 |
19 |
20 |
21 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/resources/dark/ABNetwork.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
32 |
--------------------------------------------------------------------------------
/resources/dark/ABS-member.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/dark/ABS-service.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/dark/BlockchainDataManager-service_and_project.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
--------------------------------------------------------------------------------
/resources/dark/BlockchainDataManagerApplication.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
28 |
--------------------------------------------------------------------------------
/resources/dark/BlockchainDataManagerGroupInput.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/resources/dark/BlockchainDataManagerGroupOutput.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/resources/dark/BlockchainDataManagerOutput.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/resources/dark/EthereumNetwork.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/dark/GenericService.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/dark/InfuraLayer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/dark/InfuraProject.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/dark/InfuraService.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/dark/IpfsNetwork.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/resources/dark/LocalNetwork.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/resources/dark/LocalProject.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/dark/LocalService.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/resources/dark/dependency.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/ganache/assets/fonts/FiraCode-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/resources/ganache/assets/fonts/FiraCode-Regular.ttf
--------------------------------------------------------------------------------
/resources/ganache/assets/fonts/FiraSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/resources/ganache/assets/fonts/FiraSans-Regular.ttf
--------------------------------------------------------------------------------
/resources/ganache/assets/fonts/RobotoCondensed-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/resources/ganache/assets/fonts/RobotoCondensed-Bold.ttf
--------------------------------------------------------------------------------
/resources/ganache/assets/fonts/RobotoCondensed-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/resources/ganache/assets/fonts/RobotoCondensed-Regular.ttf
--------------------------------------------------------------------------------
/resources/ganache/assets/icons/account.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/ganache/assets/icons/blocks.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
--------------------------------------------------------------------------------
/resources/ganache/assets/icons/contract.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/ganache/assets/icons/events.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/ganache/assets/icons/transactions.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/resources/light/ABNetwork.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
32 |
--------------------------------------------------------------------------------
/resources/light/ABS-member.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/light/ABS-service.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/light/BlockchainDataManager-service_and_project.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
--------------------------------------------------------------------------------
/resources/light/BlockchainDataManagerApplication.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
28 |
--------------------------------------------------------------------------------
/resources/light/BlockchainDataManagerGroupInput.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/resources/light/BlockchainDataManagerGroupOutput.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/resources/light/BlockchainDataManagerOutput.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/resources/light/EthereumNetwork.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/light/GenericService.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/light/InfuraLayer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/light/InfuraProject.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/light/InfuraService.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/light/IpfsNetwork.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/resources/light/LocalNetwork.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/resources/light/LocalProject.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/light/LocalService.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/resources/light/dependency.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/logPanel/main.css:
--------------------------------------------------------------------------------
1 | body,
2 | html {
3 | width: 100% !important;
4 | margin: 0px !important;
5 | padding: 0px !important;
6 | }
7 |
8 | div.tab-frame input {
9 | display: none;
10 | }
11 |
12 | div.tab-frame label {
13 | display: none;
14 | float: left;
15 | padding: 8px 24px;
16 | cursor: pointer;
17 | min-height: 15px;
18 | margin-right: 2px;
19 | text-transform: uppercase;
20 | font-size: 12px;
21 | }
22 |
23 | div.tab-frame label img {
24 | float: left;
25 | width: 14px;
26 | height: 14px;
27 | margin-right: 5px;
28 | }
29 |
30 | div.tab-frame input:checked + label {
31 | border-bottom: solid 1px #40e0c5;
32 | cursor: hover;
33 | }
34 |
35 | div.tab-frame div.tab {
36 | display: none;
37 | padding: 10px;
38 | clear: left;
39 | height: 85vh;
40 | overflow-y: scroll;
41 | }
42 |
43 | div.tab-frame div.tab div {
44 | white-space: pre-wrap;
45 | margin-bottom: 2px;
46 | font-family: 'Courier New';
47 | font-size: 14px;
48 | }
49 |
50 | div.tab-frame input:nth-of-type(1):checked ~ .tab:nth-of-type(1),
51 | div.tab-frame input:nth-of-type(2):checked ~ .tab:nth-of-type(2),
52 | div.tab-frame input:nth-of-type(3):checked ~ .tab:nth-of-type(3),
53 | div.tab-frame input:nth-of-type(4):checked ~ .tab:nth-of-type(4),
54 | div.tab-frame input:nth-of-type(5):checked ~ .tab:nth-of-type(5),
55 | div.tab-frame input:nth-of-type(6):checked ~ .tab:nth-of-type(6),
56 | div.tab-frame input:nth-of-type(7):checked ~ .tab:nth-of-type(7),
57 | div.tab-frame input:nth-of-type(8):checked ~ .tab:nth-of-type(8),
58 | div.tab-frame input:nth-of-type(9):checked ~ .tab:nth-of-type(9),
59 | div.tab-frame input:nth-of-type(10):checked ~ .tab:nth-of-type(10) {
60 | display: block;
61 | }
62 |
--------------------------------------------------------------------------------
/resources/walkthrough/connect-ganache.md:
--------------------------------------------------------------------------------
1 | # Connect to Ganache local blockchain and deploy contracts
2 |
3 | 
4 |
5 | With Ganache running, you can right-click on your smart contract file and select the "Deploy Contracts" option.
6 | This lists all the available networks, including those from your `truffle-config` file and networks you created using the extension (Infura and Ganache).
7 | Next, select the Ganache network and watch the extension deploy your contract to Ganache.
8 |
9 | **That’s it, now you have all you need to start building the right way!**
10 |
--------------------------------------------------------------------------------
/resources/walkthrough/create-project.md:
--------------------------------------------------------------------------------
1 | # Create new Solidity Project
2 |
3 | You can start a new Truffle project from scratch or from a Truffle Box.
4 |
5 | 
6 |
7 | [Truffle Boxes](https://trufflesuite.com/boxes/) are helpful boilerplates that allow you to focus on what makes your dapp unique.
8 | In addition to Truffle, Truffle Boxes can contain other helpful modules,
9 | Solidity contracts & libraries, front-end views and more;
10 | all the way up to complete example dapps.
11 |
--------------------------------------------------------------------------------
/resources/walkthrough/debug-transactions.md:
--------------------------------------------------------------------------------
1 | # Debug Transactions
2 |
3 | To start debugging a transaction using the extension, open the command palette with `SHIFT + CMD + P` and select "Truffle: Debug Transaction".
4 | The extension would list all the previously run transactions in chronological order.
5 | Clicking on any transaction starts the debugging process,
6 | and you can step through to gain more insight into that transaction.
7 |
8 | 
9 |
10 | 
11 |
12 | 
13 |
--------------------------------------------------------------------------------
/resources/walkthrough/deploy-contracts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/resources/walkthrough/deploy-contracts.png
--------------------------------------------------------------------------------
/resources/walkthrough/explore-commands.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trufflesuite/vscode-ext/56d0352f81d6ab96a3accde57bfc3bfe9cb484f0/resources/walkthrough/explore-commands.png
--------------------------------------------------------------------------------
/resources/walkthrough/infura-sign-in.md:
--------------------------------------------------------------------------------
1 | # Sign in to your Infura account and deploy contracts
2 |
3 | 
4 |
5 | With Infura set up, you can right-click on a contract, select the "Deploy contracts" option, and pick a Project/Network combination to deploy your contract to.
6 |
7 | 
8 |
9 | 
10 |
11 | The extension outputs information about your contract deployments to the Output tab on the VS Code command line.
12 | You also need to ensure that it's displaying output from "Truffle for VS Code" channel.
13 |
14 | 
15 |
--------------------------------------------------------------------------------
/resources/walkthrough/resources.md:
--------------------------------------------------------------------------------
1 | # Resources
2 |
3 | ## Quick Links
4 |
5 | [Marketplace](https://marketplace.visualstudio.com/items?itemName=trufflesuite-csi.truffle-vscode)
6 |
7 | [Repository](https://github.com/trufflesuite/vscode-ext)
8 |
9 | [Issues](https://github.com/trufflesuite/vscode-ext/issues)
10 |
11 | [Changelog](https://github.com/trufflesuite/vscode-ext/blob/master/CHANGELOG.md)
12 |
13 | ## Documentation
14 |
15 | [Truffle for VS Code User Guide](https://trufflesuite.com/docs/vscode-ext/)
16 |
17 | [Truffle Documentation](https://trufflesuite.com/docs)
18 |
--------------------------------------------------------------------------------
/resources/welcome/changelog.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/resources/welcome/main.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', function () {
2 | const vscode = acquireVsCodeApi();
3 |
4 | document.querySelectorAll('a').forEach((a) => {
5 | a.addEventListener('click', (e) => {
6 | vscode.postMessage(a.href ? {command: 'openLink', value: a.href} : {command: 'executeCommand', value: a.id});
7 |
8 | if (a.classList.contains('action')) {
9 | a.closest('.required-app').classList.toggle('disabled');
10 | }
11 | });
12 | });
13 |
14 | document.querySelector('#showOnStartup').addEventListener('change', function () {
15 | vscode.postMessage({command: 'toggleShowPage', value: this.checked});
16 | });
17 |
18 | window.addEventListener('message', function (event) {
19 | const message = event.data; // The JSON data our extension sent
20 | if (message.command === 'versions') {
21 | const versions = message.value;
22 | if (Array.isArray(versions)) {
23 | versions.forEach((version) => {
24 | const element = document.querySelector(`#${version.app}`);
25 | const spinner = document.querySelector(`#${version.app} .spinner`);
26 | element.classList.toggle('disabled', version.isValid);
27 | spinner.classList.toggle('spinner', false);
28 | });
29 | }
30 | } else if (message.command === 'showOnStartup') {
31 | if (!!message.value) {
32 | document.querySelector('#showOnStartup').setAttribute('checked', '');
33 | } else {
34 | document.querySelector('#showOnStartup').removeAttribute('checked');
35 | }
36 | }
37 | });
38 |
39 | vscode.postMessage({command: 'documentReady'});
40 | });
41 |
--------------------------------------------------------------------------------
/src/Models/CancellationEvent.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export class CancellationEvent extends Error {
5 | constructor(message?: string) {
6 | super(message);
7 |
8 | if (Error.captureStackTrace) {
9 | Error.captureStackTrace(this, CancellationEvent);
10 | }
11 |
12 | this.name = 'CancellationEvent';
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Models/EnumStorage.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export class EnumStorage {
5 | // contains enums for contract's fields
6 | public fields: {[key: string]: IEnumItem[]} = {};
7 |
8 | // contains enums for method's arguments from contract
9 | public methods: {[key: string]: IMethod} = {};
10 | }
11 |
12 | interface IMethod {
13 | [key: string]: IEnumItem[];
14 | }
15 |
16 | interface IEnumItem {
17 | value: number;
18 | name: string;
19 | }
20 |
--------------------------------------------------------------------------------
/src/Models/IDeployDestination.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import type {INetwork} from '@/helpers/ConfigurationReader';
5 | import type {ItemType} from './ItemType';
6 | import type {TLocalProjectOptions} from './TreeItems/LocalProject';
7 |
8 | export interface IDeployDestination {
9 | description?: string;
10 | detail?: string;
11 | label: string;
12 | networkType: ItemType;
13 | port?: number;
14 | getTruffleNetwork: () => Promise;
15 | networkId: number;
16 | options?: TLocalProjectOptions;
17 | }
18 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/CommandItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Command} from '@/Models/TreeItems/Command';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class CommandItemCreator extends ItemCreator {
8 | protected createFromObject(obj: {[key: string]: any}): Command {
9 | const {label, commandName, args} = obj;
10 |
11 | return new Command(label, commandName, args);
12 | }
13 |
14 | protected getRequiredFields(): Array<{fieldName: string; type: string}> {
15 | const requiredFields = super.getRequiredFields();
16 |
17 | return requiredFields.concat({fieldName: 'command', type: 'string'});
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/GenericNetworkNodeItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {GenericNetworkNode} from '../TreeItems/GenericNetworkNode';
5 | import {NetworkNodeItemCreator} from './NetworkNodeItemCreator';
6 |
7 | export class GenericNetworkNodeItemCreator extends NetworkNodeItemCreator {
8 | protected createFromObject(label: string, url: string, networkId: string): GenericNetworkNode {
9 | return new GenericNetworkNode(label, url, networkId);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/GenericProjectItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {GenericProject} from '@/Models/TreeItems/GenericProject';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class GenericProjectItemCreator extends ItemCreator {
8 | protected getRequiredFields(): Array<{fieldName: string; type: string}> {
9 | const requiredFields = super.getRequiredFields();
10 | requiredFields.push(
11 | ...[
12 | {fieldName: 'label', type: 'string'},
13 | {fieldName: 'port', type: 'number'},
14 | ]
15 | );
16 |
17 | return requiredFields;
18 | }
19 |
20 | protected getAdditionalConstructorArguments(obj: {[key: string]: any}): any[] {
21 | return [obj.label, obj.port, obj.description];
22 | }
23 |
24 | protected createFromObject(label: string, port: number, description?: string): GenericProject {
25 | return new GenericProject(label, port, description);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/GenericServiceItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {GenericService} from '@/Models/TreeItems/GenericService';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class GenericServiceItemCreator extends ItemCreator {
8 | protected createFromObject(): GenericService {
9 | return new GenericService();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/InfuraLayerItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {InfuraLayer} from '../TreeItems/InfuraLayer';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class InfuraLayerItemCreator extends ItemCreator {
8 | protected getRequiredFields(): Array<{fieldName: string; type: string}> {
9 | const requiredFields = super.getRequiredFields();
10 | requiredFields.push(...[{fieldName: 'label', type: 'string'}]);
11 |
12 | return requiredFields;
13 | }
14 |
15 | protected getAdditionalConstructorArguments(obj: {[key: string]: any}): any[] {
16 | return [obj.label];
17 | }
18 |
19 | protected createFromObject(label: string): InfuraLayer {
20 | return new InfuraLayer(label);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/InfuraNetworkNodeItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {InfuraNetworkNode} from '../TreeItems/InfuraNetworkNode';
5 | import {NetworkNodeItemCreator} from './NetworkNodeItemCreator';
6 |
7 | export class InfuraNetworkNodeItemCreator extends NetworkNodeItemCreator {
8 | protected createFromObject(label: string, url: string, networkId: string): InfuraNetworkNode {
9 | return new InfuraNetworkNode(label, url, networkId);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/InfuraProjectItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {InfuraProject} from '../TreeItems/InfuraProject';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class InfuraProjectItemCreator extends ItemCreator {
8 | protected getRequiredFields(): Array<{fieldName: string; type: string}> {
9 | const requiredFields = super.getRequiredFields();
10 | requiredFields.push(
11 | ...[
12 | {fieldName: 'label', type: 'string'},
13 | {fieldName: 'projectId', type: 'string'},
14 | ]
15 | );
16 |
17 | return requiredFields;
18 | }
19 |
20 | protected getAdditionalConstructorArguments(obj: {[key: string]: any}): any[] {
21 | return [obj.label, obj.projectId];
22 | }
23 |
24 | protected createFromObject(label: string, projectId: string): InfuraProject {
25 | return new InfuraProject(label, projectId);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/InfuraServiceItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {InfuraService} from '@/Models/TreeItems/InfuraService';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class InfuraServiceItemCreator extends ItemCreator {
8 | protected createFromObject(): InfuraService {
9 | return new InfuraService();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/ItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Telemetry} from '@/Telemetry';
5 | import type {IExtensionItem} from '../TreeItems/IExtensionItem';
6 |
7 | export abstract class ItemCreator {
8 | public create(obj: {[key: string]: any}): IExtensionItem {
9 | const requiredFields = this.getRequiredFields() || [];
10 |
11 | this.checkRequiredFields(obj, requiredFields);
12 |
13 | const args = this.getAdditionalConstructorArguments(obj);
14 |
15 | return this.createFromObject(...args);
16 | }
17 |
18 | protected abstract createFromObject(...args: any[]): IExtensionItem;
19 |
20 | protected getRequiredFields(): Array<{fieldName: string; type: string}> {
21 | return [{fieldName: 'itemType', type: 'number'}];
22 | }
23 |
24 | protected getAdditionalConstructorArguments(_obj: {[key: string]: any}): any[] {
25 | return [];
26 | }
27 |
28 | private checkRequiredFields(
29 | obj: {[key: string]: any},
30 | requiredFields: Array<{fieldName: string; type: string}>
31 | ): void {
32 | requiredFields.forEach((item) => {
33 | const field = obj[item.fieldName];
34 | if (field === undefined || field === null) {
35 | Telemetry.sendException(new Error(`Missed required field ${item.fieldName}.`));
36 | throw new Error(`Missed required field ${item.fieldName}. JSON: ${JSON.stringify(obj)}`);
37 | }
38 |
39 | if ((item.type === 'array' && Array.isArray(field)) || typeof field === item.type) {
40 | return;
41 | }
42 |
43 | Telemetry.sendException(new Error(`Required field ${item.fieldName} should be type ${item.type}`));
44 | throw new Error(`Required field ${item.fieldName} should be type ${item.type}. JSON: ${JSON.stringify(obj)}`);
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/LocalNetworkNodeItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {LocalNetworkNode} from '../TreeItems/LocalNetworkNode';
5 | import {NetworkNodeItemCreator} from './NetworkNodeItemCreator';
6 |
7 | export class LocalNetworkNodeItemCreator extends NetworkNodeItemCreator {
8 | protected createFromObject(label: string, url: string, networkId: string): LocalNetworkNode {
9 | return new LocalNetworkNode(label, url, networkId);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/LocalProjectItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {TLocalProjectOptions, LocalProject} from '../TreeItems/LocalProject';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class LocalProjectItemCreator extends ItemCreator {
8 | protected getRequiredFields(): Array<{fieldName: string; type: string}> {
9 | const requiredFields = super.getRequiredFields();
10 | requiredFields.push(
11 | ...[
12 | {fieldName: 'label', type: 'string'},
13 | {fieldName: 'port', type: 'number'},
14 | ]
15 | );
16 |
17 | return requiredFields;
18 | }
19 |
20 | protected getAdditionalConstructorArguments(obj: {[key: string]: any}): any[] {
21 | return [obj.label, obj.port, obj.options, obj.description];
22 | }
23 |
24 | protected createFromObject(
25 | label: string,
26 | port: number,
27 | options: TLocalProjectOptions,
28 | description: string
29 | ): LocalProject {
30 | return new LocalProject(label, port, options, description);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/LocalServiceItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {LocalService} from '../TreeItems/LocalService';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class LocalServiceItemCreator extends ItemCreator {
8 | protected createFromObject(): LocalService {
9 | return new LocalService();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/NetworkNodeItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ItemCreator} from './ItemCreator';
5 |
6 | export abstract class NetworkNodeItemCreator extends ItemCreator {
7 | protected getRequiredFields(): Array<{fieldName: string; type: string}> {
8 | const requiredFields = super.getRequiredFields();
9 | requiredFields.push(
10 | ...[
11 | {fieldName: 'label', type: 'string'},
12 | {fieldName: 'url', type: 'string'},
13 | {fieldName: 'networkId', type: 'string'},
14 | ]
15 | );
16 |
17 | return requiredFields;
18 | }
19 |
20 | protected getAdditionalConstructorArguments(obj: {[key: string]: any}): any[] {
21 | return [obj.label, obj.url, obj.networkId];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Models/ItemCreators/NullableItemCreator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Nullable} from '../TreeItems/Nullable';
5 | import {ItemCreator} from './ItemCreator';
6 |
7 | export class NullableItemCreator extends ItemCreator {
8 | protected createFromObject(): Nullable {
9 | return new Nullable();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/ItemType.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export enum ItemType {
5 | NULLABLE = 0,
6 | // INFO = 1, // NOT USED
7 | COMMAND = 2,
8 | // AZURE_BLOCKCHAIN_SERVICE = 3,
9 | // LOCAL_NETWORK_GROUP = 4, // NOT USED
10 | // ETHEREUM_TEST_GROUP = 5, // NOT USED
11 | // ETHEREUM_MAIN_GROUP = 6, // NOT USED
12 | // AZURE_BLOCKCHAIN_PROJECT = 7,
13 | // LOCAL_NETWORK = 8, // NOT USED
14 | // ETHEREUM_TEST_NETWORK = 9, // NOT USED
15 | // ETHEREUM_MAIN_NETWORK = 10, // NOT USED
16 | MEMBER = 11,
17 | LOCAL_SERVICE = 30,
18 | LOCAL_PROJECT = 31,
19 | LOCAL_NETWORK_NODE = 32,
20 | INFURA_SERVICE = 40,
21 | INFURA_PROJECT = 41,
22 | INFURA_NETWORK_NODE = 42,
23 | INFURA_LAYER = 43,
24 | GENERIC_SERVICE = 60,
25 | GENERIC_PROJECT = 61,
26 | GENERIC_NETWORK_NODE = 62,
27 | }
28 |
--------------------------------------------------------------------------------
/src/Models/QuickPickItems/InfuraProjectItem.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {QuickPickItem} from 'vscode';
5 | import {IInfuraEndpointDto} from '../../services/infuraService/InfuraDto/IInfuraEndpointDto';
6 |
7 | export class InfuraProjectItem implements QuickPickItem {
8 | public readonly label: string;
9 | public readonly description: string;
10 | public readonly projectId: string;
11 | public readonly endpoints: IInfuraEndpointDto;
12 |
13 | constructor(label: string, projectId: string, endpoints: IInfuraEndpointDto, description?: string) {
14 | this.label = label;
15 | this.description = description || '';
16 | this.projectId = projectId;
17 | this.endpoints = endpoints;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Models/QuickPickItems/NetworkForContractItem.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {QuickPickItem} from 'vscode';
5 |
6 | export class NetworkForContractItem implements QuickPickItem {
7 | public readonly label: string;
8 | public readonly host: string;
9 | public readonly contractAddress: string;
10 |
11 | constructor(label: string, host: string, contractAddress: string) {
12 | this.label = label;
13 | this.host = host;
14 | this.contractAddress = contractAddress;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/Command.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ItemType} from '../ItemType';
5 | import {Service} from './Service';
6 |
7 | export class Command extends Service {
8 | constructor(label: string, commandName: string, args?: any[]) {
9 | super(ItemType.COMMAND, `-> ${label}`, {});
10 |
11 | this.command = {
12 | arguments: args,
13 | command: commandName,
14 | title: `-> ${label}`,
15 | };
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/GenericNetworkNode.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {INetwork} from '@/helpers/ConfigurationReader';
5 | import {URL} from 'url';
6 | import {Constants} from '@/Constants';
7 | import {ItemType} from '@/Models/ItemType';
8 | import {NetworkNode} from './NetworkNode';
9 |
10 | export class GenericNetworkNode extends NetworkNode {
11 | public readonly port: number;
12 |
13 | constructor(label: string, url: URL | string, networkId: number | string) {
14 | super(ItemType.GENERIC_NETWORK_NODE, label, Constants.treeItemData.network.generic, url, networkId);
15 |
16 | this.port = parseInt(this.url.port, 10) || Constants.defaultLocalhostPort;
17 | }
18 |
19 | public async getTruffleNetwork(): Promise {
20 | const network = await super.getTruffleNetwork();
21 |
22 | network.options.host = this.url.hostname || Constants.localhost;
23 | network.options.port = this.port;
24 |
25 | return network;
26 | }
27 |
28 | protected async getGasPrice(): Promise {
29 | return undefined;
30 | }
31 |
32 | protected async getGasLimit(): Promise {
33 | return undefined;
34 | }
35 |
36 | protected defaultProtocol(): string {
37 | return Constants.networkProtocols.http;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/GenericProject.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '../../Constants';
5 | import {IDeployDestination} from '../IDeployDestination';
6 | import {ItemType} from '../ItemType';
7 | import {GenericNetworkNode} from './GenericNetworkNode';
8 | import {Project} from './Project';
9 |
10 | export class GenericProject extends Project {
11 | public readonly port: number;
12 |
13 | constructor(label: string, port: number, description?: string) {
14 | super(ItemType.GENERIC_PROJECT, label, Constants.treeItemData.project.generic, description);
15 |
16 | this.port = port;
17 | }
18 |
19 | public toJSON(): {[p: string]: any} {
20 | const obj = super.toJSON();
21 |
22 | obj.port = this.port;
23 |
24 | return obj;
25 | }
26 |
27 | public async getDeployDestinations(): Promise {
28 | const {generic} = Constants.treeItemData.service;
29 |
30 | const getDeployName = (labelNode: string) => [generic.prefix, this.label, labelNode].join('_');
31 |
32 | return Promise.all(
33 | (this.getChildren() as GenericNetworkNode[]).map(async (node) => {
34 | return {
35 | description: await node.getRPCAddress(),
36 | detail: generic.label,
37 | getTruffleNetwork: async () => {
38 | const truffleNetwork = await node.getTruffleNetwork();
39 | truffleNetwork.name = getDeployName(node.label);
40 | return truffleNetwork;
41 | },
42 | label: getDeployName(node.label),
43 | networkId: node.networkId,
44 | networkType: node.itemType,
45 | port: node.port,
46 | } as IDeployDestination;
47 | })
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/GenericService.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '../../Constants';
5 | import {ItemType} from '../ItemType';
6 | import {Service} from './Service';
7 |
8 | export class GenericService extends Service {
9 | constructor() {
10 | super(
11 | ItemType.GENERIC_SERVICE,
12 | Constants.treeItemData.service.generic.label,
13 | Constants.treeItemData.service.generic
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/Group.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ItemType} from '../ItemType';
5 | import {ExtensionItem, ExtensionItemData} from './ExtensionItem';
6 |
7 | type GroupTypes = ItemType.MEMBER;
8 |
9 | export abstract class Group extends ExtensionItem {
10 | protected constructor(itemType: GroupTypes, label: string, data: ExtensionItemData) {
11 | super(itemType, label, data);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/IExtensionItem.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {TreeItem} from 'vscode';
5 | import {ItemType} from '../ItemType';
6 |
7 | export interface IExtensionItem extends TreeItem {
8 | itemType: ItemType;
9 |
10 | getParent(): IExtensionItem | null;
11 | getChildren(): IExtensionItem[];
12 | addParent(parent: IExtensionItem): void;
13 | addChild(child: IExtensionItem): void;
14 | removeChild(child: IExtensionItem): void;
15 | setChildren(children: IExtensionItem[]): void;
16 | toJSON(): {[key: string]: any};
17 | }
18 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/InfuraLayer.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ItemType} from '../ItemType';
5 | import {Layer} from './Layer';
6 | import {Constants} from '../../Constants';
7 |
8 | export class InfuraLayer extends Layer {
9 | constructor(label: string) {
10 | super(ItemType.INFURA_LAYER, label, Constants.treeItemData.layer.infura);
11 | }
12 |
13 | public toJSON(): {[p: string]: any} {
14 | const obj = super.toJSON();
15 |
16 | return obj;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/InfuraNetworkNode.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {INetwork} from '@/helpers/ConfigurationReader';
5 | import {URL} from 'url';
6 | import {Constants} from '@/Constants';
7 | import {showInputBox} from '@/helpers/userInteraction';
8 | import {ItemType} from '@/Models/ItemType';
9 | import {MnemonicNetworkNode} from './MnemonicNetworkNode';
10 |
11 | export class InfuraNetworkNode extends MnemonicNetworkNode {
12 | constructor(label: string, url: URL | string, networkId: number | string, description?: string) {
13 | super(ItemType.INFURA_NETWORK_NODE, label, Constants.treeItemData.network.infura, url, networkId, description);
14 | }
15 |
16 | public async getTruffleNetwork(): Promise {
17 | return await super.getTruffleNetwork();
18 | }
19 |
20 | protected async getGasPrice(): Promise {
21 | const value = await showInputBox({
22 | ignoreFocusOut: true,
23 | prompt: Constants.paletteLabels.valueOrDefault(
24 | Constants.propertyLabels.gasPrice,
25 | Constants.defaultContractSettings.gasPrice
26 | ),
27 | validateInput: this.validation,
28 | });
29 |
30 | if (!value) {
31 | return Constants.defaultContractSettings.gasPrice;
32 | }
33 |
34 | return parseInt(value, 10);
35 | }
36 |
37 | protected async getGasLimit(): Promise {
38 | const value = await showInputBox({
39 | ignoreFocusOut: true,
40 | prompt: Constants.paletteLabels.valueOrDefault(
41 | Constants.propertyLabels.gasLimit,
42 | Constants.defaultContractSettings.gasLimit
43 | ),
44 | validateInput: this.validation,
45 | });
46 |
47 | if (!value) {
48 | return Constants.defaultContractSettings.gasLimit;
49 | }
50 |
51 | return parseInt(value, 10);
52 | }
53 |
54 | protected defaultProtocol(): string {
55 | return Constants.networkProtocols.https;
56 | }
57 |
58 | private validation(value: string): string | undefined {
59 | return value && !value.match(new RegExp(/^\d+$/g))
60 | ? Constants.validationMessages.valueShouldBeNumberOrEmpty
61 | : undefined;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/InfuraProject.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '../../Constants';
5 | import {IDeployDestination} from '../IDeployDestination';
6 | import {ItemType} from '../ItemType';
7 | import {InfuraNetworkNode} from './InfuraNetworkNode';
8 | import {Layer} from './Layer';
9 | import {Project} from './Project';
10 |
11 | export class InfuraProject extends Project {
12 | public readonly projectId: string;
13 |
14 | constructor(label: string, projectId: string) {
15 | super(ItemType.INFURA_PROJECT, label, Constants.treeItemData.project.infura);
16 |
17 | this.projectId = projectId;
18 | }
19 |
20 | public toJSON(): {[p: string]: any} {
21 | const obj = super.toJSON();
22 |
23 | obj.projectId = this.projectId;
24 |
25 | return obj;
26 | }
27 |
28 | public async getDeployDestinations(): Promise {
29 | const {infura} = Constants.treeItemData.service;
30 |
31 | const getDeployName = (labelNode: string) => [infura.prefix, this.label, labelNode].join('_');
32 |
33 | const destinations: IDeployDestination[] = [];
34 |
35 | Promise.all(
36 | (this.getChildren() as Layer[]).map(async (layer) => {
37 | (layer.getChildren() as InfuraNetworkNode[]).map(async (node) => {
38 | destinations.push({
39 | description: await node.getRPCAddress(),
40 | detail: infura.label,
41 | getTruffleNetwork: async () => {
42 | const truffleNetwork = await node.getTruffleNetwork();
43 | truffleNetwork.name = getDeployName(node.label);
44 | return truffleNetwork;
45 | },
46 | label: getDeployName(node.label),
47 | networkId: Number.parseInt(node.networkId.toString()),
48 | networkType: node.itemType,
49 | });
50 | });
51 | })
52 | );
53 |
54 | return destinations;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/InfuraService.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '../../Constants';
5 | import {ItemType} from '../ItemType';
6 | import {Service} from './Service';
7 |
8 | export class InfuraService extends Service {
9 | constructor() {
10 | super(ItemType.INFURA_SERVICE, Constants.treeItemData.service.infura.label, Constants.treeItemData.service.infura);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/Layer.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ItemType} from '../ItemType';
5 | import {ExtensionItem, ExtensionItemData} from './ExtensionItem';
6 |
7 | type LayerTypes = ItemType.INFURA_LAYER;
8 |
9 | export abstract class Layer extends ExtensionItem {
10 | protected constructor(itemType: LayerTypes, label: string, data: ExtensionItemData, description?: string) {
11 | super(itemType, label, data, description);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/LocalNetworkNode.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {INetwork} from '@/helpers/ConfigurationReader';
5 | import {URL} from 'url';
6 | import {Constants} from '@/Constants';
7 | import {ItemType} from '@/Models/ItemType';
8 | import {NetworkNode} from './NetworkNode';
9 |
10 | export class LocalNetworkNode extends NetworkNode {
11 | public readonly port: number;
12 |
13 | constructor(label: string, url: URL | string, networkId: number | string) {
14 | super(ItemType.LOCAL_NETWORK_NODE, label, Constants.treeItemData.network.local, url, networkId);
15 |
16 | this.port = parseInt(this.url.port, 10) || Constants.defaultLocalhostPort;
17 | }
18 |
19 | public async getTruffleNetwork(): Promise {
20 | const network = await super.getTruffleNetwork();
21 |
22 | network.options.host = this.url.hostname || Constants.localhost;
23 | network.options.port = this.port;
24 |
25 | return network;
26 | }
27 |
28 | protected async getGasPrice(): Promise {
29 | return undefined;
30 | }
31 |
32 | protected async getGasLimit(): Promise {
33 | return undefined;
34 | }
35 |
36 | protected defaultProtocol(): string {
37 | return Constants.networkProtocols.http;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/LocalProject.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '../../Constants';
5 | import {IDeployDestination} from '../IDeployDestination';
6 | import {ItemType} from '../ItemType';
7 | import {LocalNetworkNode} from './LocalNetworkNode';
8 | import {Project} from './Project';
9 |
10 | export type TLocalProjectOptions = {
11 | isForked: boolean;
12 | forkedNetwork: string;
13 | url: string;
14 | blockNumber: number;
15 | };
16 |
17 | export class LocalProject extends Project {
18 | constructor(label: string, readonly port: number, readonly options: TLocalProjectOptions, description: string) {
19 | super(ItemType.LOCAL_PROJECT, label, Constants.treeItemData.project.local, description);
20 | }
21 |
22 | public toJSON(): {[p: string]: any} {
23 | const obj = super.toJSON();
24 |
25 | obj.port = this.port;
26 | obj.options = this.options;
27 |
28 | return obj;
29 | }
30 |
31 | public async getDeployDestinations(): Promise {
32 | const {local} = Constants.treeItemData.service;
33 |
34 | const getDeployName = (labelNode: string) => [local.prefix, this.label, labelNode].join('_');
35 |
36 | return Promise.all(
37 | (this.getChildren() as LocalNetworkNode[]).map(async (node) => {
38 | return {
39 | description: await node.getRPCAddress(),
40 | detail: local.label,
41 | getTruffleNetwork: async () => {
42 | const truffleNetwork = await node.getTruffleNetwork();
43 | truffleNetwork.name = getDeployName(node.label);
44 | return truffleNetwork;
45 | },
46 | label: getDeployName(node.label),
47 | networkId: node.networkId,
48 | networkType: node.itemType,
49 | port: node.port,
50 | options: this.options,
51 | } as IDeployDestination;
52 | })
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/LocalService.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '../../Constants';
5 | import {ItemType} from '../ItemType';
6 | import {Service} from './Service';
7 |
8 | export class LocalService extends Service {
9 | constructor() {
10 | super(ItemType.LOCAL_SERVICE, Constants.treeItemData.service.local.label, Constants.treeItemData.service.local);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/NetworkNode.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {INetwork} from '@/helpers/ConfigurationReader';
5 | import {URL} from 'url';
6 | import {Constants} from '@/Constants';
7 | import {ItemType} from '@/Models/ItemType';
8 | import {ExtensionItem, ExtensionItemData} from './ExtensionItem';
9 |
10 | const protocolRegExp = new RegExp(
11 | '^(' +
12 | Constants.networkProtocols.http +
13 | '|' +
14 | Constants.networkProtocols.https +
15 | '|' +
16 | Constants.networkProtocols.ftp +
17 | '|' +
18 | Constants.networkProtocols.file +
19 | ').*',
20 | 'i'
21 | );
22 |
23 | type NetworkNodeTypes = ItemType.LOCAL_NETWORK_NODE | ItemType.INFURA_NETWORK_NODE | ItemType.GENERIC_NETWORK_NODE;
24 |
25 | export abstract class NetworkNode extends ExtensionItem {
26 | public readonly networkId: number | string;
27 | public readonly url: URL;
28 |
29 | protected constructor(
30 | itemType: NetworkNodeTypes,
31 | label: string,
32 | data: ExtensionItemData,
33 | url: URL | string,
34 | networkId: number | string,
35 | description?: string
36 | ) {
37 | networkId = networkId === '*' ? networkId : parseInt(networkId + '', 10);
38 |
39 | super(itemType, label, data, description);
40 |
41 | this.url = this.prepareUrl(url);
42 | this.networkId = networkId;
43 | }
44 |
45 | public toJSON(): {[key: string]: any} {
46 | const obj = super.toJSON();
47 |
48 | obj.url = this.url.toString();
49 | obj.networkId = this.networkId.toString();
50 |
51 | return obj;
52 | }
53 |
54 | public async getRPCAddress(): Promise {
55 | if (!this.url) {
56 | return '';
57 | }
58 |
59 | return this.url.pathname === '/' ? this.url.origin : this.url.href;
60 | }
61 |
62 | public async getTruffleNetwork(): Promise {
63 | return {
64 | name: this.label,
65 | options: {
66 | gasPrice: await this.getGasPrice(),
67 | network_id: this.networkId,
68 | },
69 | };
70 | }
71 |
72 | protected abstract getGasPrice(): Promise;
73 |
74 | protected abstract getGasLimit(): Promise;
75 |
76 | protected abstract defaultProtocol(): string;
77 |
78 | private prepareUrl(url: URL | string): URL {
79 | if (typeof url === 'string') {
80 | if (!url.match(protocolRegExp)) {
81 | url = `${this.defaultProtocol()}${url}`;
82 | }
83 |
84 | url = new URL(url);
85 | }
86 |
87 | return url;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/Nullable.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ItemType} from '../ItemType';
5 | import {ExtensionItem, ExtensionItemData} from './ExtensionItem';
6 |
7 | export class Nullable extends ExtensionItem {
8 | constructor() {
9 | super(ItemType.NULLABLE, '', {} as ExtensionItemData);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/Project.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {IDeployDestination} from '../IDeployDestination';
5 | import {ItemType} from '../ItemType';
6 | import {ExtensionItem, ExtensionItemData} from './ExtensionItem';
7 | import {NetworkNode} from './NetworkNode';
8 |
9 | type ProjectTypes = ItemType.LOCAL_PROJECT | ItemType.INFURA_PROJECT | ItemType.GENERIC_PROJECT;
10 |
11 | export abstract class Project extends ExtensionItem {
12 | protected constructor(itemType: ProjectTypes, label: string, data: ExtensionItemData, description?: string) {
13 | super(itemType, label, data, description);
14 | }
15 |
16 | public async getRPCAddress(): Promise {
17 | const networkNodes = this.children.filter((child) => child instanceof NetworkNode) as NetworkNode[];
18 | if (networkNodes.length === 0) {
19 | return '';
20 | }
21 |
22 | // FIXME: suggest user the list of nodes
23 | return networkNodes[0].getRPCAddress();
24 | }
25 |
26 | public abstract getDeployDestinations(): Promise;
27 | }
28 |
--------------------------------------------------------------------------------
/src/Models/TreeItems/Service.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import type {ItemType} from '../ItemType';
5 | import {ExtensionItem, type ExtensionItemData} from './ExtensionItem';
6 |
7 | export type ServiceTypes =
8 | | ItemType.LOCAL_SERVICE
9 | | ItemType.INFURA_SERVICE
10 | | ItemType.GENERIC_SERVICE
11 | | ItemType.COMMAND;
12 |
13 | export abstract class Service extends ExtensionItem {
14 | protected constructor(itemType: ServiceTypes, label: string, data: ExtensionItemData) {
15 | super(itemType, label, data);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/commands/ContractCommands.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {StatusBarItems} from '@/Models/StatusBarItems/Contract';
5 |
6 | export namespace ContractCommands {
7 | /**
8 | * This function is responsible for enabling or disabling the automatic deployment of contracts
9 | *
10 | * @param contractStatusBarItem The object representing the status bar contract item.
11 | */
12 | export function setEnableOrDisableAutoDeploy(contractStatusBarItem: StatusBarItems.Contract): void {
13 | // Gets the current auto deploy current state and invert its value
14 | const enableOrDisableAutoDeploy = contractStatusBarItem.getState() ? false : true;
15 |
16 | // Set the new state value
17 | contractStatusBarItem.setState(enableOrDisableAutoDeploy);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/commands/GenericCommands.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {commands, window} from 'vscode';
5 | import {Constants, RequiredApps} from '../Constants';
6 | import {required} from '../helpers/required';
7 | import type {GenericProject} from '../Models/TreeItems/GenericProject';
8 | import {GenericService} from '@/services/generic/GenericService';
9 | import {TreeManager} from '@/services/tree/TreeManager';
10 | import {Telemetry} from '@/Telemetry';
11 | import type {ProjectView} from '@/views/NetworksView';
12 |
13 | export namespace GenericCommands {
14 | // Command to bind to UI commands
15 | export async function checkForConnection(projectView?: ProjectView): Promise {
16 | Telemetry.sendEvent('GenericCommands.checkForConnection.commandStarted');
17 |
18 | if (!(await required.checkApps(RequiredApps.node))) {
19 | Telemetry.sendEvent('GenericCommands.checkForConnection.nodeIsNotInstalled');
20 | void commands.executeCommand('truffle-vscode.showRequirementsPage');
21 | return;
22 | }
23 |
24 | const project: GenericProject = projectView?.extensionItem as GenericProject;
25 | project.description = await GenericService.getClientVersion(project.port);
26 |
27 | void window.showInformationMessage(Constants.genericCommandStrings.serverRunning);
28 |
29 | TreeManager.saveState();
30 | await commands.executeCommand('truffle-vscode.refresh');
31 |
32 | Telemetry.sendEvent('GenericCommands.checkForConnection.commandFinished');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/commands/InfuraCommands.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '../Constants';
5 | import {showQuickPickMany} from '../helpers/userInteraction';
6 | import {InfuraResourceExplorer} from '@/resourceExplorers/InfuraResourceExplorer';
7 | import {InfuraServiceClient} from '@/services/infuraService/InfuraServiceClient';
8 |
9 | export namespace InfuraCommands {
10 | export async function signIn(): Promise {
11 | await InfuraServiceClient.signIn();
12 | }
13 |
14 | export async function signOut(): Promise {
15 | await InfuraServiceClient.signOut();
16 | }
17 |
18 | export async function showProjectsFromAccount(): Promise {
19 | const infuraResourceExplorer = new InfuraResourceExplorer();
20 | const allProjects = await infuraResourceExplorer.getProjectsForQuickPick();
21 |
22 | const selectedProjects = await showQuickPickMany(allProjects, {
23 | canPickMany: true,
24 | ignoreFocusOut: true,
25 | placeHolder: Constants.placeholders.selectProjects,
26 | });
27 |
28 | await InfuraServiceClient.setExcludedProjects(allProjects, selectedProjects);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/commands/SdkCoreCommands.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Memento, window, Uri} from 'vscode';
5 | import {Constants} from '@/Constants';
6 | import {getConfigurationAsync} from '@/helpers/userSettings';
7 | import {IExtensionAdapter, TruffleExtensionAdapter} from '@/services/extensionAdapter';
8 |
9 | class SdkCoreCommands {
10 | private extensionAdapter!: IExtensionAdapter;
11 |
12 | public async initialize(_globalState: Memento): Promise {
13 | const sdk = await this.getCoreSdk();
14 | this.extensionAdapter = this.getExtensionAdapter(sdk.userValue ? sdk.userValue : sdk.defaultValue);
15 | this.extensionAdapter.validateExtension().catch((error) => {
16 | void window.showErrorMessage(error.message);
17 | });
18 | }
19 |
20 | /**
21 | * Triggers the build process to compile smart contracts.
22 | *
23 | * @param contractUri if provided, it is the `Uri` of the smart contract to be compiled.
24 | */
25 | public async build(contractUri?: Uri): Promise {
26 | return this.extensionAdapter.build(contractUri);
27 | }
28 |
29 | /**
30 | * Deploys, _i.e._, `migrate`, smart contracts into a Network.
31 | *
32 | * @param contractUri FIXME: Is this used?
33 | */
34 | public async deploy(contractUri?: Uri): Promise {
35 | return this.extensionAdapter.deploy(contractUri);
36 | }
37 |
38 | private async getCoreSdk() {
39 | return getConfigurationAsync(Constants.userSettings.coreSdkSettingsKey);
40 | }
41 |
42 | private getExtensionAdapter(sdk: string): IExtensionAdapter {
43 | switch (sdk) {
44 | default:
45 | return new TruffleExtensionAdapter();
46 | }
47 | }
48 | }
49 |
50 | export const sdkCoreCommands = new SdkCoreCommands();
51 |
--------------------------------------------------------------------------------
/src/debugAdapter/configuration/debugAdapterDescriptorFactory.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {
5 | DebugAdapterDescriptor,
6 | DebugAdapterDescriptorFactory,
7 | DebugAdapterExecutable,
8 | DebugAdapterServer,
9 | DebugSession,
10 | ProviderResult,
11 | } from 'vscode';
12 |
13 | import Net from 'net';
14 | import {SolidityDebugSession} from '../debugSession';
15 |
16 | export default class TruffleDebugAdapterDescriptorFactory implements DebugAdapterDescriptorFactory {
17 | private _server?: Net.Server;
18 |
19 | public createDebugAdapterDescriptor(
20 | _session: DebugSession,
21 | _executable: DebugAdapterExecutable | undefined
22 | ): ProviderResult {
23 | if (!this._server) {
24 | // start listening on a random port
25 | this._server = Net.createServer((socket) => {
26 | const debugSession = new SolidityDebugSession();
27 | debugSession.setRunAsServer(true);
28 | debugSession.start(socket as NodeJS.ReadableStream, socket);
29 | }).listen(0);
30 | }
31 |
32 | // make VS Code connect to debug server
33 | const address: any = this._server.address();
34 | return new DebugAdapterServer(address.port);
35 | }
36 |
37 | public dispose() {
38 | if (this._server) {
39 | this._server.close();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/debugAdapter/configuration/debugConfigurationProvider.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {
5 | CancellationToken,
6 | DebugConfiguration,
7 | DebugConfigurationProvider,
8 | ProviderResult,
9 | WorkspaceFolder,
10 | } from 'vscode';
11 |
12 | export default class TruffleDebuggerConfigurationProvider implements DebugConfigurationProvider {
13 | /**
14 | * Massage a debug configuration just before a debug session is being launched,
15 | * e.g. add all missing attributes to the debug configuration.
16 | */
17 | public resolveDebugConfiguration(
18 | _folder: WorkspaceFolder | undefined,
19 | config: DebugConfiguration,
20 | _token?: CancellationToken
21 | ): ProviderResult {
22 | return config;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/debugAdapter/configuration/debuggerConfiguration.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {debug, ExtensionContext} from 'vscode';
5 | import {DEBUG_TYPE} from '../constants/debugAdapter';
6 | import DebugAdapterTrackerFactory from '../debugAdapterTracker/debugAdapterTrackerFactory';
7 | import DebugAdapterDescriptorFactory from './debugAdapterDescriptorFactory';
8 | import DebuggerConfigurationProvider from './debugConfigurationProvider';
9 |
10 | export class DebuggerConfiguration {
11 | public static initialize(context: ExtensionContext) {
12 | const debugConfigProvider = new DebuggerConfigurationProvider();
13 | context.subscriptions.push(debug.registerDebugConfigurationProvider(DEBUG_TYPE, debugConfigProvider));
14 |
15 | const factory = new DebugAdapterDescriptorFactory();
16 | context.subscriptions.push(debug.registerDebugAdapterDescriptorFactory(DEBUG_TYPE, factory));
17 | context.subscriptions.push(factory);
18 |
19 | const debugAdapterTrackerFactory = new DebugAdapterTrackerFactory();
20 | const trackerFactory = debug.registerDebugAdapterTrackerFactory(DEBUG_TYPE, debugAdapterTrackerFactory);
21 | context.subscriptions.push(trackerFactory);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/debugAdapter/constants/debugAdapter.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export const EVENT_TYPES = {
5 | breakpointValidated: 'breakpointValidated',
6 | end: 'end',
7 | launched: 'launched',
8 | stopOnBreakpoint: 'stopOnBreakpoint',
9 | stopOnEntry: 'stopOnEntry',
10 | stopOnException: 'stopOnException',
11 | stopOnStepIn: 'stopOnStepIn',
12 | stopOnStepOut: 'stopOnStepOut',
13 | stopOnStepOver: 'stopOnStepOver',
14 | stopped: 'stopped',
15 | };
16 |
17 | export const EVENT_REASONS = {
18 | breakpoint: 'breakpoint',
19 | changed: 'changed',
20 | entry: 'entry',
21 | exception: 'exception',
22 | stepIn: 'stepin',
23 | stepOut: 'stepout',
24 | stepOver: 'step',
25 | };
26 |
27 | // we don't support multiple threads, so we can use a hardcoded ID for the default thread
28 | export const MAIN_THREAD = {
29 | id: 1,
30 | name: 'thread 1',
31 | };
32 |
33 | export const EVALUATE_REQUEST_TYPES = {
34 | hover: 'hover',
35 | watch: 'watch',
36 | };
37 |
38 | export const DEBUG_TYPE = 'truffle';
39 |
40 | export const ERROR_MESSAGE_ID = 1;
41 |
--------------------------------------------------------------------------------
/src/debugAdapter/constants/debugSessionCommands.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export const GET_INSTRUCTIONS = 'requestInstructions';
5 | export const GET_CURRENT_INSTRUCTION = 'requestCurrentInstruction';
6 |
--------------------------------------------------------------------------------
/src/debugAdapter/debugAdapterTracker/debugAdapterTracker.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {DebugAdapterTracker, DebugSession, window} from 'vscode';
5 | import InstructionView from '../instructionsView/instructionView';
6 |
7 | import {EVENT_TYPES} from '../constants/debugAdapter';
8 | import {GET_CURRENT_INSTRUCTION, GET_INSTRUCTIONS} from '../constants/debugSessionCommands';
9 | import {IInstruction} from '../models/IInstruction';
10 | import InstructionTreeNode from '../instructionsView/instructionTreeNode';
11 |
12 | export default class SolidityDebugAdapterTracker implements DebugAdapterTracker {
13 | private session: DebugSession;
14 | private instructionView: InstructionView;
15 |
16 | constructor(session: DebugSession) {
17 | this.session = session;
18 | this.instructionView = new InstructionView();
19 | }
20 |
21 | public onDidSendMessage(message: any): void {
22 | if (message.success === false) {
23 | window.showErrorMessage('Error occured in debug mode: ' + message.body.error.format);
24 | return;
25 | }
26 | switch (message.event) {
27 | case EVENT_TYPES.launched: // init instructions after launch
28 | this.requestForInstructions();
29 | return;
30 | case EVENT_TYPES.stopped: // get current instruction on every stop event
31 | this.requestForCurrentInstruction();
32 | return;
33 | }
34 | switch (message.command) {
35 | case GET_INSTRUCTIONS:
36 | this.updateInstructionView(message.body.instructions);
37 | return;
38 | case GET_CURRENT_INSTRUCTION:
39 | this.revealInstruction(message.body.currentInstruction);
40 | return;
41 | }
42 | }
43 |
44 | private requestForInstructions() {
45 | this.session.customRequest(GET_INSTRUCTIONS);
46 | }
47 |
48 | private requestForCurrentInstruction() {
49 | this.session.customRequest(GET_CURRENT_INSTRUCTION);
50 | }
51 |
52 | private updateInstructionView(instructions: IInstruction[]): void {
53 | const element = this.instructionView.getRootElement();
54 | this.instructionView.update(element, instructions);
55 | }
56 |
57 | private revealInstruction(instruction: IInstruction): InstructionTreeNode {
58 | return this.instructionView.revealInstruction(instruction);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/debugAdapter/debugAdapterTracker/debugAdapterTrackerFactory.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult} from 'vscode';
5 | import SolidityDebugAdapterTracker from './debugAdapterTracker';
6 |
7 | export default class SolidityDebugAdapterTrackerFactory implements DebugAdapterTrackerFactory {
8 | public createDebugAdapterTracker(session: DebugSession): ProviderResult {
9 | return new SolidityDebugAdapterTracker(session);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/debugAdapter/instructionsView/instructionDataManager.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {IInstruction} from '../models/IInstruction';
5 | import InstructionTreeNode from './instructionTreeNode';
6 |
7 | export default class InstructionDataManager {
8 | private instructionObject: any = {};
9 |
10 | public load(instructions: IInstruction[]) {
11 | this.instructionObject = this.mapInstructionsArrayToObject(instructions);
12 | }
13 |
14 | public getChidren(element?: InstructionTreeNode): string[] {
15 | if (!element) {
16 | return Object.keys(this.instructionObject).map((k) => k);
17 | }
18 |
19 | const item = this.getItemByPath(element.getPaths());
20 | if (item === undefined) {
21 | return [];
22 | }
23 | return Object.keys(item);
24 | }
25 |
26 | public getItem(element: InstructionTreeNode): any {
27 | return this.getItemByPath(element.getPaths());
28 | }
29 |
30 | public getItemParent(element: InstructionTreeNode): any {
31 | return this.getItemByPath(element.getParentPaths());
32 | }
33 |
34 | // Map from array to object in order to used in view
35 | // [{pc:1,op: ''},{pc:2,op:''}] ==> { 1:{pc:1,op:''}, 2:{pc:2,op:''}}
36 | private mapInstructionsArrayToObject(steps: IInstruction[]): any {
37 | const res: any = {};
38 | steps.forEach((s) => {
39 | res[s.pc] = s;
40 | });
41 |
42 | return res;
43 | }
44 |
45 | private getItemByPath(paths: string[]): any {
46 | if (paths.length === 0) {
47 | return void 0;
48 | }
49 | let item = this.instructionObject;
50 | paths.forEach((key) => {
51 | item = item[key];
52 | });
53 | return item;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/debugAdapter/instructionsView/instructionDataProvider.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Event, EventEmitter, ProviderResult, TreeDataProvider, TreeItem, TreeItemCollapsibleState} from 'vscode';
5 | import {IInstruction} from '../models/IInstruction';
6 | import InstructionDataManager from './instructionDataManager';
7 | import InstructionTreeNode from './instructionTreeNode';
8 |
9 | export default class InstructionDataProvider implements TreeDataProvider {
10 | public _onDidChangeTreeData: EventEmitter = new EventEmitter();
11 | public readonly onDidChangeTreeData: Event = this._onDidChangeTreeData.event;
12 |
13 | private instructionDataManager: InstructionDataManager;
14 |
15 | constructor(instructionDataManager: InstructionDataManager) {
16 | this.instructionDataManager = instructionDataManager;
17 | }
18 |
19 | public refresh(element: InstructionTreeNode, newInstructions: IInstruction[]) {
20 | this.instructionDataManager.load(newInstructions);
21 | this._onDidChangeTreeData.fire(element);
22 | }
23 |
24 | public getChildren(element?: InstructionTreeNode): ProviderResult {
25 | const items = this.instructionDataManager.getChidren(element);
26 | return items.map((e) => new InstructionTreeNode(e, element));
27 | }
28 |
29 | public getTreeItem(element: InstructionTreeNode): TreeItem {
30 | const item = this.instructionDataManager.getItem(element);
31 | const isSpecificObjectValueType = this.isSpecificObjectValueType(item);
32 | const collapsibleState = isSpecificObjectValueType
33 | ? TreeItemCollapsibleState.Collapsed
34 | : TreeItemCollapsibleState.None;
35 |
36 | return {
37 | collapsibleState,
38 | id: element.getId(),
39 | label: this.generateTreeItemLabel(element.getKey(), item, isSpecificObjectValueType),
40 | };
41 | }
42 |
43 | public getParent(element: InstructionTreeNode): ProviderResult {
44 | return element.getParent();
45 | }
46 |
47 | private generateTreeItemLabel(treeItemKey: string, treeItemValue: any, isSpecificObjectValueType: boolean) {
48 | return isSpecificObjectValueType ? treeItemKey : `${treeItemKey}: ${JSON.stringify(treeItemValue)}`;
49 | }
50 |
51 | // TODO: refactroign - same method in variablesHandler
52 | private isSpecificObjectValueType(item: any) {
53 | return !Array.isArray(item) && item !== null && item !== undefined && typeof item === 'object';
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/debugAdapter/instructionsView/instructionTreeNode.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {IInstruction} from '../models/IInstruction';
5 |
6 | export default class InstructionTreeNode {
7 | private key: string;
8 | private path: string;
9 | private parent?: InstructionTreeNode;
10 |
11 | constructor(key?: string, parent?: InstructionTreeNode, instructionData?: IInstruction) {
12 | if (!key && (!instructionData || (!instructionData.pc && instructionData.pc !== 0))) {
13 | throw new Error('Incorrect input params');
14 | }
15 |
16 | const nodeKey = instructionData ? instructionData.pc.toString() : key || '';
17 | this.key = nodeKey;
18 | this.parent = parent;
19 | this.path = this.generatePath(nodeKey, parent);
20 | }
21 |
22 | public getId(): string {
23 | return this.path;
24 | }
25 |
26 | public getKey(): string {
27 | return this.key;
28 | }
29 |
30 | public getParent(): InstructionTreeNode | undefined {
31 | return this.parent;
32 | }
33 |
34 | public getParentPaths(): string[] {
35 | return this.path.split(/\//).slice(1, this.path.length - 1); // not take first empty element and last
36 | }
37 |
38 | public getPaths(): string[] {
39 | return this.path.split(/\//).slice(1); // not take first empty element
40 | }
41 |
42 | private generatePath(key: string, parent?: InstructionTreeNode) {
43 | const parentPath = parent ? parent.path : '';
44 | return `${parentPath}/${key}`;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/debugAdapter/instructionsView/instructionView.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {TreeView, window} from 'vscode';
5 | import {IInstruction} from '../models/IInstruction';
6 | import InstructionDataManager from './instructionDataManager';
7 | import InstructionDataProvider from './instructionDataProvider';
8 | import InstructionTreeNode from './instructionTreeNode';
9 |
10 | const INSTRUCTION_VIEW_ID = 'truffle-vscode.InstructionView';
11 |
12 | export default class InstructionView {
13 | private view: TreeView;
14 | private dataProvider: InstructionDataProvider;
15 | constructor() {
16 | const dataManager = new InstructionDataManager();
17 | this.dataProvider = new InstructionDataProvider(dataManager);
18 | this.view = window.createTreeView(INSTRUCTION_VIEW_ID, {
19 | treeDataProvider: this.dataProvider,
20 | showCollapseAll: true,
21 | });
22 | }
23 |
24 | public update(element: InstructionTreeNode, newInstructions: IInstruction[]) {
25 | this.dataProvider.refresh(element, newInstructions);
26 | }
27 |
28 | public revealInstruction(instruction: IInstruction): InstructionTreeNode {
29 | const treeNode = new InstructionTreeNode(undefined, undefined, instruction);
30 | if (this.view.visible) {
31 | this.view.reveal(treeNode, {focus: true, select: true, expand: true});
32 | }
33 | return treeNode;
34 | }
35 |
36 | getRootElement(): InstructionTreeNode {
37 | return this.view.selection[0];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/debugAdapter/models/ICallInfo.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface ICallInfo {
5 | column: number;
6 | file: string;
7 | line: number;
8 | method: string;
9 | }
10 |
--------------------------------------------------------------------------------
/src/debugAdapter/models/IContractJsonModel.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface IContractJsonModel {
5 | abi: [];
6 | ast: any;
7 | bytecode: string;
8 | compiler: any;
9 | contractName: string;
10 | deployedBytecode: string;
11 | deployedSourceMap: string;
12 | source: string;
13 | sourceMap: string;
14 | sourcePath: string;
15 | networks: {
16 | [networkId: string]: {
17 | address: string;
18 | };
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/src/debugAdapter/models/IExpressionEval.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface IExpressionEval {
5 | result: string;
6 | variablesReference: number;
7 | }
8 |
--------------------------------------------------------------------------------
/src/debugAdapter/models/IInstruction.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface IInstruction {
5 | pc: number;
6 | op: string;
7 | }
8 |
--------------------------------------------------------------------------------
/src/debugAdapter/models/ITransactionInputData.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface ITransactionInputData {
5 | methodName: string;
6 | params: any[];
7 | }
8 |
--------------------------------------------------------------------------------
/src/debugAdapter/models/ITransactionResponse.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface ITransactionResponse {
5 | hash: string;
6 | methodName: string;
7 | contractName: string;
8 | }
9 |
--------------------------------------------------------------------------------
/src/debugAdapter/models/debuggerTypes.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {DebugProtocol} from '@vscode/debugprotocol';
5 | import {EVENT_TYPES} from '../constants/debugAdapter';
6 |
7 | export namespace DebuggerTypes {
8 | export interface IBreakpoint {
9 | id: number;
10 | sourceId: string;
11 | line: number;
12 | }
13 |
14 | export interface IFrame {
15 | file: string;
16 | line: number;
17 | column: number;
18 | }
19 |
20 | /**
21 | * Represents the arguments needed to initiate a new Truffle `DebugSession` request.
22 | *
23 | * All properties in this interface are defined as optional given that the Debugger
24 | * can be started from a [launch configuration](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations),
25 | * where any property might be missing.
26 | *
27 | * `package.json` also defines these properties.
28 | */
29 | export interface DebugArgs {
30 | /**
31 | * The transaction hash to debug.
32 | */
33 | txHash?: string;
34 |
35 | /**
36 | * Directory of the Truffle project where to find the Truffle config file.
37 | */
38 | workingDirectory?: string;
39 |
40 | /**
41 | * Provider's URL of the Ethereum network to connect to.
42 | */
43 | providerUrl?: string;
44 |
45 | /**
46 | * Network name of the Ethereum network to connect to.
47 | */
48 | network?: string;
49 |
50 | /**
51 | * When set, do not try to fetch external contract sources when debugging a forked network instance.
52 | * When the network is not being forked, this flag is ignored.
53 | */
54 | disableFetchExternal?: boolean;
55 | }
56 |
57 | // The interface should always match schema in the package.json.
58 | export interface ILaunchRequestArguments extends DebugProtocol.LaunchRequestArguments, DebugArgs {
59 | // TODO: Are these attributes being used? If not we should remove it in a future PR.
60 | // Automatically stop target after launch. If not specified, target does not stop.
61 | stopOnEntry?: boolean;
62 | // enable logging the Debug Adapter Protocol
63 | trace?: boolean;
64 | host?: string;
65 | files?: string[];
66 | }
67 |
68 | export class LaunchedEvent implements DebugProtocol.Event {
69 | public event: string = EVENT_TYPES.launched;
70 | public seq = 1000;
71 | public type = 'event';
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/debugAdapter/transaction/transactionInputDataDecoder.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import abiDecoder from 'abi-decoder';
5 | import {ITransactionInputData} from '../models/ITransactionInputData';
6 |
7 | const TRANSACTION_DEFAULT_METHOD_NAME = 'constructor';
8 |
9 | export class TransactionInputDataDecoder {
10 | public addContractAbi(abi: []) {
11 | abiDecoder.addABI(abi);
12 | }
13 |
14 | // Use addContractAbi before using decode
15 | public async decode(txInput: string): Promise {
16 | const decodedInput = abiDecoder.decodeMethod(txInput);
17 | return decodedInput
18 | ? {methodName: decodedInput.name, params: decodedInput.params}
19 | : {methodName: TRANSACTION_DEFAULT_METHOD_NAME, params: []};
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/debugAdapter/types/@truffle/debugger.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | declare module '@truffle/debugger' {
5 | // Fixme: bumping TS might make all this work...
6 | import {provider as Web3Provider} from 'web3-core';
7 |
8 | // import type Web3 from "web3";
9 | interface Selectors {
10 | // FIXME: there are more selectors in the latest release we can add in here?
11 | sourcemapping: any;
12 | evm: any;
13 | controller: any;
14 | trace: any;
15 | }
16 |
17 | const selectors: Selectors;
18 |
19 | interface Session {
20 | removeAllBreakpoints: () => Promise;
21 | view: (selectors: any) => any;
22 | addBreakpoint: (breakPoint: any) => unknown;
23 | variables: () => Promise;
24 | continueUntilBreakpoint: () => Promise;
25 | stepNext: () => Promise;
26 | stepInto: () => Promise;
27 | stepOut: () => Promise;
28 | }
29 |
30 | interface Debugger {
31 | connect: () => Session;
32 | }
33 |
34 | /**
35 | * More permissively typed Object
36 | */
37 | type DebuggerOptions = {
38 | provider: Web3Provider;
39 | compilations?: Array;
40 | lightMode: boolean;
41 | };
42 |
43 | /**
44 | * Instantiates a Debugger for a given transaction hash.
45 | * Throws on failure. If you want a more failure-tolerant method,
46 | * use forProject and then do a session.load inside a try.
47 | *
48 | * @param {String} txHash - transaction hash with leading "0x"
49 | * @param {{contracts: Array, files: Array, provider: Web3Provider, compilations: Array}} options -
50 | * @return {Debugger} instance
51 | */
52 | function forTx(txHash: string, options: DebuggerOptions): Promise;
53 |
54 | export {selectors, Selectors, forTx, Session, DebuggerOptions};
55 | }
56 |
--------------------------------------------------------------------------------
/src/debugAdapter/types/@truffle/environment.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | declare module '@truffle/environment' {
5 | import TruffleConfig from '@truffle/config';
6 | export class Environment {
7 | static async detect(config: TruffleConfig): Promise;
8 | }
9 | export {Environment};
10 | }
11 |
--------------------------------------------------------------------------------
/src/debugAdapter/types/@truffle/provider.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | declare module '@truffle/provider' {
5 | interface IProviderOptions {
6 | provider?: any;
7 | host?: string;
8 | port?: number;
9 | websockets?: boolean;
10 | }
11 | function create(networkOptions: IProviderOptions): any;
12 | export {create};
13 | }
14 |
--------------------------------------------------------------------------------
/src/debugAdapter/types/@truffle/workflow-compile.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 | declare module '@truffle/workflow-compile' {
4 | import type {Compilation, CompiledContract} from '@truffle/compile-common';
5 |
6 | interface Artifacts {
7 | /**
8 | * An list of codec-style compilations; this method of specifying a project
9 | * is mostly intended for internal Truffle use for now, but you can see the
10 | * documentation of the Compilation type if you want to use it.
11 | */
12 | compilations: Array;
13 | /**
14 | * A list of contracts involved in the compilation.
15 | */
16 | contracts: Array;
17 | }
18 |
19 | /**
20 | * Compiles contracts found in contracts_directory and
21 | * saves them in contracts_build_directory
22 | *
23 | * @param {TruffleConfig} config - from '@truffle/config' - Config.detect({ workingDirectory: workingDirectory })
24 | * @return {Artifacts}
25 | */
26 | function compile(config: TruffleConfig): Promise;
27 |
28 | export {Artifacts, compile};
29 | }
30 |
--------------------------------------------------------------------------------
/src/debugAdapter/types/abi-decoder.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | declare module 'abi-decoder' {
5 | interface Decoded {
6 | name: string;
7 | params: any[];
8 | }
9 |
10 | function addABI(abi: []): void;
11 | function decodeMethod(input: string): Decoded;
12 |
13 | export {addABI, decodeMethod};
14 | }
15 |
--------------------------------------------------------------------------------
/src/debugAdapter/types/web3.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | declare namespace Web3 {
5 | interface IProvider {
6 | currentProvider: any;
7 | }
8 |
9 | interface IBlockResponse {
10 | number: number;
11 | transactions: string[];
12 | }
13 |
14 | interface ITransactionResponse {
15 | input: string; // encoded methodName and params
16 | }
17 |
18 | interface ITransactionReceiptResponse {
19 | from: string;
20 | to?: string;
21 | contractAddress?: string;
22 | }
23 |
24 | interface IBatchRequest {
25 | add: (request: any) => void;
26 | execute: () => Promise;
27 | }
28 |
29 | interface IRequest {
30 | request: (...args: any[]) => any;
31 | }
32 |
33 | interface IWeb3Eth extends IProvider {
34 | net: {
35 | getId: () => Promise;
36 | };
37 | getBlock: any;
38 | getTransaction: any;
39 | getTransactionReceipt: any;
40 | getBlockNumber: any;
41 | currentProvider: any;
42 | getAccounts: any;
43 | getBalance: any;
44 | getGasPrice: any;
45 | }
46 |
47 | const providers: {
48 | HttpProvider: new (providerUrl: string) => IProvider;
49 | WebsocketProvider: new (providerUrl: string) => IProvider;
50 | };
51 | }
52 |
53 | // eslint-disable-next-line no-redeclare
54 | declare class Web3 {
55 | static IBatchRequest: any;
56 | constructor(provider: Web3.IProvider);
57 |
58 | eth: Web3.IWeb3Eth;
59 | BatchRequest: new () => Web3.IBatchRequest;
60 | }
61 |
62 | declare module 'web3' {
63 | export = Web3;
64 | }
65 |
--------------------------------------------------------------------------------
/src/helpers/checkTruffleConfigTemplate.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | const path = require('path');
5 |
6 | try {
7 | const hdwalletNodeModulePath = path.join(process.cwd(), 'node_modules', '@truffle/hdwallet-provider');
8 | require(hdwalletNodeModulePath);
9 | require.cache[require.resolve(hdwalletNodeModulePath)].exports = function HDWallet(...args) {
10 | this.mnemonic = args[0];
11 | this.url = args[1];
12 | };
13 | } catch (err) {
14 | // ignore
15 | }
16 |
17 | const truffleConfigName = process.argv.length >= 3 ? process.argv[2] : 'truffle-config.js';
18 |
19 | const truffleConfig = require(path.join(process.cwd(), truffleConfigName));
20 |
21 | const getCircularReplacer = () => {
22 | const seen = new WeakSet();
23 | return (k, v) => {
24 | if (typeof v === 'object' && v !== null) {
25 | if (seen.has(v)) {
26 | return;
27 | }
28 | seen.add(v);
29 | }
30 |
31 | if (typeof v === 'function') {
32 | if (k !== 'provider') {
33 | return v.toString();
34 | }
35 |
36 | return v.call(truffleConfig);
37 | }
38 |
39 | return v;
40 | };
41 | };
42 |
43 | let message = JSON.stringify(truffleConfig, getCircularReplacer());
44 |
45 | process.send({command: 'truffleConfig', message: message}, () => process.exit());
46 |
--------------------------------------------------------------------------------
/src/helpers/git.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {RequiredApps} from '@/Constants';
5 | import {Telemetry} from '@/Telemetry';
6 | import {executeCommand} from './command';
7 | import {required} from './required';
8 |
9 | export async function gitInit(workingDirectory: string): Promise {
10 | if (!(await required.checkRequiredApps())) {
11 | return;
12 | }
13 |
14 | if (!(await isRepoExists(workingDirectory))) {
15 | await executeCommand(workingDirectory, RequiredApps.git, 'init');
16 | }
17 | }
18 |
19 | async function isRepoExists(workingDirectory: string): Promise {
20 | try {
21 | await executeCommand(workingDirectory, RequiredApps.git, 'rev-parse', '--git-dir');
22 | } catch (error) {
23 | Telemetry.sendException(error as Error);
24 | return false;
25 | }
26 | return true;
27 | }
28 |
--------------------------------------------------------------------------------
/src/helpers/shell.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {tryExecuteCommand} from './command';
5 |
6 | const isWin = process.platform === 'win32';
7 |
8 | export async function killPort(port: string | number): Promise {
9 | const pid = await findPid(port);
10 |
11 | return killPid(pid);
12 | }
13 |
14 | export async function killPid(pid = NaN): Promise {
15 | if (isNaN(pid)) {
16 | return;
17 | }
18 |
19 | return tryExecuteCommand(undefined, killPidCommand(pid)).then(() => undefined);
20 | }
21 |
22 | export async function findPid(port: string | number): Promise {
23 | const result = await tryExecuteCommand(undefined, findPidCommand(port));
24 |
25 | return parsePid(result.cmdOutput);
26 | }
27 |
28 | function killPidCommand(pid: number): string {
29 | return isWin ? `taskkill /PID ${pid} /F` : `kill -TERM ${pid}`;
30 | }
31 |
32 | function findPidCommand(port: string | number): string {
33 | return isWin
34 | ? `netstat -ano -p tcp | find "LISTENING" | findstr /r /c:":${port} *[^ ]*:[^ ]*"`
35 | : `lsof -i tcp:${port} | grep LISTEN | awk '{print $2}'`;
36 | }
37 |
38 | function parsePid(stdout: string): number {
39 | const pid = stdout.match(/\s*\d+\s+$/);
40 |
41 | return pid ? parseInt(pid[0].trim(), 10) : Number.NaN;
42 | }
43 |
--------------------------------------------------------------------------------
/src/helpers/uriHandlerController.ts:
--------------------------------------------------------------------------------
1 | import {startDebugging} from '@/commands/DebuggerCommands';
2 | import {Telemetry} from '@/Telemetry';
3 | import {type Uri, type UriHandler, window} from 'vscode';
4 |
5 | /**
6 | * This enum is used to identify the different types of commands that can be executed.
7 | */
8 | enum Commands {
9 | /**
10 | * The command to start the debugger.
11 | */
12 | debug = 'debug',
13 | }
14 |
15 | export class UriHandlerController implements UriHandler {
16 | /**
17 | * This function is responsible for handling the `truffle-vscode` protocol callings.
18 | *
19 | * @param uri The URI to handle.
20 | */
21 | async handleUri(uri: Uri): Promise {
22 | // Parse the URI to get the command and the parameters.
23 | const command = uri.path.replace('/', '');
24 | const searchParams = new URLSearchParams(uri.query);
25 |
26 | // Checks the command and executes the corresponding action.
27 | switch (command) {
28 | case Commands.debug: {
29 | // Convert the URI parameters to a `DebugArgs` object.
30 | // The `??` operator converts `null` to `undefined`.
31 | const args = {
32 | txHash: searchParams.get('txHash') ?? undefined,
33 | workingDirectory: searchParams.get('workingDirectory') ?? undefined,
34 | providerUrl: searchParams.get('providerUrl') ?? undefined,
35 | network: searchParams.get('network') ?? undefined,
36 | disableFetchExternal: !!searchParams.get('disableFetchExternal'),
37 | };
38 |
39 | // Calls the debugger with the given parameters.
40 | await startDebugging(args);
41 | break;
42 | }
43 | default:
44 | void window.showWarningMessage(`Unrecognized action to handle \`${command}\``);
45 | }
46 |
47 | Telemetry.sendEvent('UriHandler.handleUri', {command});
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/helpers/userSettings.ts:
--------------------------------------------------------------------------------
1 | import {workspace} from 'vscode';
2 |
3 | export function getConfigurationAsync(key: string): {defaultValue: string; userValue: string} {
4 | const config = workspace.getConfiguration().inspect(key);
5 |
6 | const defaultValue = config!.defaultValue as string;
7 | const userValue = config!.globalValue as string;
8 | return {defaultValue, userValue};
9 | }
10 |
--------------------------------------------------------------------------------
/src/helpers/vscodeEnvironment.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {env} from 'vscode';
5 |
6 | export async function writeToClipboard(text: string): Promise {
7 | return env.clipboard.writeText(text);
8 | }
9 |
--------------------------------------------------------------------------------
/src/pages/Changelog.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import fs from 'fs-extra';
5 | import semver from 'semver';
6 | import {commands, type ExtensionContext} from 'vscode';
7 | import {Constants} from '@/Constants';
8 | import {Telemetry} from '@/Telemetry';
9 | import {BasicWebView, type IWebViewConfig} from './BasicWebView';
10 |
11 | export class ChangelogPage extends BasicWebView {
12 | protected readonly config: IWebViewConfig;
13 |
14 | constructor(context: ExtensionContext) {
15 | super(context);
16 | this.config = Object.assign({}, Constants.webViewPages.changelog);
17 | }
18 |
19 | public async checkAndShow(): Promise {
20 | const storedVersion = this.context.globalState.get(Constants.globalStateKeys.truffleExtensionVersion);
21 | if (storedVersion && semver.gte(storedVersion, Constants.extensionVersion)) {
22 | return;
23 | }
24 |
25 | this.context.globalState.update(Constants.globalStateKeys.truffleExtensionVersion, Constants.extensionVersion);
26 |
27 | Telemetry.sendEvent(Constants.telemetryEvents.webPages.showWebPage, {
28 | trigger: 'auto',
29 | viewType: this.config.viewType,
30 | });
31 |
32 | return this.createAndShow();
33 | }
34 |
35 | protected async setShowOnStartupFlagAtFirstTime(): Promise {
36 | return true;
37 | }
38 |
39 | protected async getHtmlForWebview(): Promise {
40 | if (this.panel) {
41 | const resourcePath = this.panel.webview.asWebviewUri(this.rootPath).toString();
42 | const html = await fs.readFile(this.config.path, 'utf8');
43 | const content = await fs.readFile(Constants.webViewPages.changelog.changelogPath, 'utf8');
44 | const htmlContent = (await commands.executeCommand('markdown.api.render', content)) as string;
45 |
46 | return html.replace(/{{root}}/g, resourcePath).replace(/{{content}}/g, htmlContent);
47 | }
48 | return '';
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/pages/Requirements.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022. Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ExtensionContext} from 'vscode';
5 | import {Constants} from '@/Constants';
6 | import {required} from '@/helpers/required';
7 | import {BasicWebView, IWebViewConfig} from './BasicWebView';
8 |
9 | export class RequirementsPage extends BasicWebView {
10 | protected readonly config: IWebViewConfig;
11 |
12 | constructor(context: ExtensionContext) {
13 | super(context);
14 | this.config = Object.assign({}, Constants.webViewPages.requirements);
15 | }
16 |
17 | protected async setShowOnStartupFlagAtFirstTime(): Promise {
18 | return true;
19 | }
20 |
21 | protected async receiveMessage(message: {[key: string]: any}): Promise {
22 | await super.receiveMessage(message);
23 |
24 | if (!this.panel) {
25 | return;
26 | }
27 |
28 | if (message.command === 'documentReady') {
29 | await this.postMessage({
30 | command: 'versions',
31 | value: await required.getAllVersions(),
32 | });
33 | }
34 |
35 | if (message.command === 'executeCommand') {
36 | if (message.value === 'installNpm') {
37 | await required.installNpm();
38 | }
39 |
40 | if (message.value === 'installTruffle') {
41 | await required.installTruffle();
42 | }
43 |
44 | if (message.value === 'installGanache') {
45 | await required.installGanache();
46 | }
47 | }
48 | }
49 |
50 | protected async getHtmlForWebview(): Promise {
51 | let html = await super.getHtmlForWebview();
52 | if (html !== '') {
53 | // let's get the versions we expect and inject them into the page...
54 | const versions = await required.getAllVersions();
55 | versions.forEach((v) => {
56 | html = html.replace(new RegExp('{{' + v.app + '}}', 'g'), mapRequiredVersion(v.requiredVersion));
57 | html = html.replace(new RegExp('{{' + v.app + '-installed}}', 'g'), v.version);
58 | // change the CSS on installed version... green/pink depending on valid/invalid...
59 | html = html.replace(new RegExp('{{' + v.app + '-version}}', 'g'), v.isValid ? 'version' : 'versionInvalid');
60 | });
61 | }
62 | return html;
63 | }
64 | }
65 |
66 | const mapRequiredVersion = (requiredVersion: string | {min: string; max: string}) =>
67 | typeof requiredVersion === 'string' ? requiredVersion : `^${requiredVersion.min} - ⌵${requiredVersion.max}`;
68 |
--------------------------------------------------------------------------------
/src/services/HttpService.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import requestPromise from 'request-promise';
5 | import {Constants} from '@/Constants';
6 | import {Telemetry} from '@/Telemetry';
7 |
8 | const requestTimeout = 10000;
9 |
10 | export namespace HttpService {
11 | export async function sendRPCRequest(
12 | host: string,
13 | methodName: string,
14 | parameters?: string[]
15 | ): Promise<{result?: any; error?: any} | undefined> {
16 | const address = hasProtocol(host) ? host : `${Constants.networkProtocols.http}${host}`;
17 | return requestPromise
18 | .post(address, {
19 | body: {
20 | id: 1,
21 | jsonrpc: '2.0',
22 | method: methodName,
23 | params: parameters || [],
24 | },
25 | json: true,
26 | timeout: requestTimeout,
27 | })
28 | .catch((_errorMessage) => {
29 | Telemetry.sendException(new Error(`HttpService.sendRPCRequest has done with error for method: ${methodName}`));
30 | return undefined;
31 | });
32 | }
33 |
34 | export async function sendHttpGetRequest(url: string): Promise<{result?: any; error?: any} | undefined> {
35 | const address = hasProtocol(url) ? url : `${Constants.networkProtocols.http}${url}`;
36 | return requestPromise
37 | .get(address, {
38 | timeout: requestTimeout,
39 | resolveWithFullResponse: true,
40 | })
41 | .then((response) => response.statusCode)
42 | .catch((_errorMessage) => {
43 | Telemetry.sendException(new Error(`HttpService.sendHttpGetRequest has done with error for URL: ${url}`));
44 | return undefined;
45 | });
46 | }
47 |
48 | function hasProtocol(host: string): boolean {
49 | return host.indexOf(Constants.networkProtocols.http) === 0 || host.indexOf(Constants.networkProtocols.https) === 0;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/services/MnemonicRepository.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs-extra';
2 | import type {Memento} from 'vscode';
3 | import {Constants} from '@/Constants';
4 |
5 | class ExtensionMnemonicRepository {
6 | private globalState?: Memento;
7 |
8 | public initialize(globalState: Memento): void {
9 | this.globalState = globalState;
10 | }
11 |
12 | public getMnemonic(filePath: string): string {
13 | return fs.readFileSync(filePath).toString().trim();
14 | }
15 |
16 | public getAllMnemonicPaths(): string[] {
17 | if (this.globalState) {
18 | return this.globalState.get(Constants.globalStateKeys.mnemonicStorageKey, []) as string[];
19 | }
20 |
21 | return [];
22 | }
23 |
24 | public getExistedMnemonicPaths(): string[] {
25 | return this.getAllMnemonicPaths().filter((path) => fs.existsSync(path));
26 | }
27 |
28 | public saveMnemonicPath(filePath: string): void {
29 | if (this.globalState) {
30 | const storage = (this.globalState.get(Constants.globalStateKeys.mnemonicStorageKey) as string[]) || [];
31 | this.globalState.update(Constants.globalStateKeys.mnemonicStorageKey, [...storage, filePath]);
32 | }
33 | }
34 |
35 | public MaskMnemonic(mnemonic: string) {
36 | return mnemonic ? `${mnemonic.slice(0, 3)} ... ${mnemonic.slice(-3)}` : Constants.placeholders.emptyLineText;
37 | }
38 | }
39 |
40 | export const MnemonicRepository = new ExtensionMnemonicRepository();
41 |
--------------------------------------------------------------------------------
/src/services/contract/AbstractAdapter.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {ContractInstance} from './ContractInstance';
5 |
6 | export abstract class AbstractAdapter {
7 | public abstract initialize(): Promise;
8 | public abstract getContractInstances(contractName: string): Promise;
9 | public abstract getContractInstance(contractName: string, instanceId: string): Promise;
10 | public abstract getChangedContractInstances(truffleConfigPath?: string): Promise;
11 | public abstract dispose(): Promise;
12 | }
13 |
--------------------------------------------------------------------------------
/src/services/contract/Contract.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | // More information about schema see here
5 | // https://github.com/trufflesuite/truffle-contract-schema
6 |
7 | export class Contract {
8 | public readonly abi: Array<{[key: string]: any}>;
9 | public readonly ast: {[key: string]: any};
10 | public readonly bytecode: string;
11 | public readonly compiler: {[key: string]: any};
12 | public readonly contractName: string;
13 | public readonly deployedBytecode: string;
14 | public readonly metadata: string;
15 | public readonly networks: {[key: string]: any};
16 | public readonly schemaVersion: string;
17 | public readonly source: string;
18 | public readonly sourcePath: string;
19 | public readonly updatedAt: string;
20 |
21 | // This keys were ignored sourceMap, deployedSourceMap, legacyAST, devdoc, userdoc
22 |
23 | constructor(contract: {[key: string]: any}) {
24 | this.abi = contract.abi;
25 | this.ast = contract.ast;
26 | this.bytecode = contract.bytecode;
27 | this.compiler = contract.compiler;
28 | this.contractName = contract.contractName;
29 | this.deployedBytecode = contract.deployedBytecode;
30 | this.metadata = contract.metadata;
31 | this.networks = contract.networks;
32 | this.schemaVersion = contract.schemaVersion;
33 | this.source = contract.source;
34 | this.sourcePath = contract.sourcePath;
35 | this.updatedAt = contract.updatedAt;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/services/contract/ContractDB.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {EventEmitter} from 'events';
5 | import {Telemetry} from '../../Telemetry';
6 | import type {AbstractAdapter} from './AbstractAdapter';
7 | import type {ContractInstance} from './ContractInstance';
8 | import {InMemoryAdapter} from './InMemoryAdapter';
9 | import {TruffleDBAdapter} from './TruffleDBAdapter';
10 |
11 | class ExtensionContractDB {
12 | public readonly bus: EventEmitter;
13 | private adapter?: AbstractAdapter;
14 |
15 | constructor() {
16 | this.bus = new EventEmitter();
17 | }
18 |
19 | public async initialize(adapterType: AdapterType): Promise {
20 | Telemetry.sendEvent('ContractDB.initialize', {adapterType});
21 | if (this.adapter) {
22 | await this.adapter.dispose();
23 | this.adapter = undefined;
24 | }
25 |
26 | if (adapterType === AdapterType.TRUFFLE_DB) {
27 | this.adapter = new TruffleDBAdapter();
28 | }
29 |
30 | if (adapterType === AdapterType.IN_MEMORY) {
31 | this.adapter = new InMemoryAdapter();
32 | }
33 |
34 | if (!this.adapter) {
35 | Telemetry.sendEvent('ContractDB.initialize.unknownAdapterType', {adapterType});
36 | return;
37 | }
38 |
39 | await this.adapter.initialize();
40 | }
41 |
42 | public async getContractInstances(contractName: string): Promise {
43 | if (this.adapter) {
44 | return [...(await this.adapter.getContractInstances(contractName))]; // get a copy of original array
45 | }
46 |
47 | return [];
48 | }
49 |
50 | public async getContractInstance(contractName: string, instanceId: string): Promise {
51 | return this.adapter && (await this.adapter.getContractInstance(contractName, instanceId));
52 | }
53 |
54 | public async updateContracts(): Promise {
55 | if (this.adapter) {
56 | const contracts: ContractInstance[] = await this.adapter.getChangedContractInstances();
57 | const contractNames = contracts
58 | .map((contract) => contract.contractName)
59 | .filter((contractName, index, arr) => arr.indexOf(contractName) === index);
60 |
61 | this.bus.emit('updateContracts', contractNames);
62 | }
63 | }
64 |
65 | public async dispose(): Promise {
66 | return this.adapter && (await this.adapter.dispose());
67 | }
68 | }
69 |
70 | export enum AdapterType {
71 | IN_MEMORY = 'InMemory',
72 | TRUFFLE_DB = 'TruffleDB',
73 | }
74 |
75 | export const ContractDB = new ExtensionContractDB();
76 |
--------------------------------------------------------------------------------
/src/services/contract/ContractInstance.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import uuid from 'uuid';
5 | import {Contract} from './Contract';
6 | import {Network} from './Network';
7 |
8 | export class ContractInstance {
9 | public readonly id: string;
10 | public readonly contract: Contract;
11 | public readonly contractName: string;
12 | public readonly network: Network;
13 |
14 | public readonly address?: string;
15 | public readonly transactionHash?: string;
16 |
17 | constructor(contract: Contract, network: Network) {
18 | this.id = uuid.v4();
19 | this.contract = contract;
20 | this.network = network;
21 | this.contractName = contract.contractName;
22 |
23 | const networks = contract.networks;
24 | const deployedNetwork = networks[network.id] || {};
25 |
26 | this.address = deployedNetwork.address || '';
27 | this.transactionHash = deployedNetwork.transactionHash;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/services/contract/ContractInstanceWithMetadata.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {extractEnumsInfoSafe} from '@/helpers/enumExtractor';
5 | import {EnumStorage} from '@/Models/EnumStorage';
6 | import {Contract} from './Contract';
7 | import {ContractInstance} from './ContractInstance';
8 | import {Network} from './Network';
9 | import {Provider} from './Provider';
10 |
11 | export class ContractInstanceWithMetadata extends ContractInstance {
12 | public readonly provider: Provider | null;
13 | public readonly updateDate: string;
14 | public enumsInfo: EnumStorage;
15 |
16 | constructor(contract: Contract, network: Network, provider: Provider | null) {
17 | super(contract, network);
18 |
19 | this.updateDate = new Date(contract.updatedAt).toISOString();
20 | this.provider = provider;
21 | this.enumsInfo = extractEnumsInfoSafe(contract.contractName, contract.ast);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/services/contract/Network.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface Network {
5 | id: string;
6 | name?: string;
7 | }
8 |
--------------------------------------------------------------------------------
/src/services/contract/Provider.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | interface HttpHeader {
5 | name: string;
6 | value: string;
7 | }
8 |
9 | interface ProviderOptions {
10 | host?: string;
11 | protocol?: string;
12 | timeout?: number;
13 | headers?: HttpHeader[];
14 | withCredentials?: boolean;
15 | mnemonic?: string;
16 | }
17 |
18 | export interface Provider {
19 | host: string;
20 | options?: ProviderOptions;
21 | }
22 |
--------------------------------------------------------------------------------
/src/services/contract/TruffleDBAdapter.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {AbstractAdapter} from './AbstractAdapter';
5 | import {ContractInstance} from '@/services/contract/ContractInstance';
6 |
7 | export class TruffleDBAdapter extends AbstractAdapter {
8 | public async initialize(): Promise {
9 | return;
10 | }
11 |
12 | public async getContractInstances(_contractName: string): Promise {
13 | throw new Error('Method is not implemented yet');
14 | }
15 |
16 | public async getContractInstance(_contractName: string, _instanceId: string): Promise {
17 | throw new Error('Method is not implemented yet');
18 | }
19 |
20 | public async getChangedContractInstances(): Promise {
21 | throw new Error('Method is not implemented yet');
22 | }
23 |
24 | public async dispose(): Promise {
25 | return;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/services/dashboard/DashboardServiceClient.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '@/Constants';
5 | import {Telemetry} from '@/Telemetry';
6 | import {HttpService} from '../HttpService';
7 |
8 | export async function isDashboardRunning(port: number | string): Promise {
9 | try {
10 | const response = await HttpService.sendHttpGetRequest(`http://${Constants.localhost}:${port}`);
11 | return (response && response === 200) || false;
12 | } catch (error) {
13 | Telemetry.sendException(error as Error);
14 | return false;
15 | }
16 | }
17 |
18 | export async function waitDashboardStarted(port: number | string, maxRetries = 1): Promise {
19 | const retry = async (retries: number) => {
20 | if (retries < maxRetries) {
21 | if (await isDashboardRunning(port)) {
22 | return;
23 | }
24 | await new Promise((resolve) => setTimeout(resolve, Constants.dashboardRetryTimeout));
25 | await retry(retries + 1);
26 | } else {
27 | const error = new Error(Constants.ganacheCommandStrings.cannotStartServer);
28 | Telemetry.sendException(error);
29 | throw error;
30 | }
31 | };
32 | await retry(0);
33 | }
34 |
--------------------------------------------------------------------------------
/src/services/extensionAdapter/IExtensionAdapter.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 | import {Uri} from 'vscode';
4 |
5 | export interface IExtensionAdapter {
6 | validateExtension: () => Promise;
7 |
8 | build: (contractUri?: Uri) => Promise;
9 | deploy: (contractUri?: Uri) => Promise;
10 | }
11 |
--------------------------------------------------------------------------------
/src/services/extensionAdapter/TruffleExtensionAdapter.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Uri} from 'vscode';
5 | import {TruffleCommands} from '../../commands/TruffleCommands';
6 | import {IExtensionAdapter} from './IExtensionAdapter';
7 |
8 | export class TruffleExtensionAdapter implements IExtensionAdapter {
9 | public validateExtension = async (): Promise => {
10 | // throw new Error("Method not implemented.");
11 | };
12 |
13 | public build = async (uri?: Uri): Promise => {
14 | return TruffleCommands.buildContracts(uri);
15 | };
16 |
17 | public deploy = async (uri?: Uri): Promise => {
18 | return TruffleCommands.deployContracts(uri);
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/src/services/extensionAdapter/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export * from './IExtensionAdapter';
5 | export * from './TruffleExtensionAdapter';
6 |
--------------------------------------------------------------------------------
/src/services/ganache/GanacheServiceClient.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '@/Constants';
5 | import {Telemetry} from '@/Telemetry';
6 | import {HttpService} from '../HttpService';
7 |
8 | export async function isGanacheServer(port: number | string): Promise {
9 | try {
10 | const response = await HttpService.sendRPCRequest(
11 | `http://${Constants.localhost}:${port}`,
12 | Constants.rpcMethods.netListening
13 | );
14 | return (response && !!response.result) || false;
15 | } catch (error) {
16 | Telemetry.sendException(error as Error);
17 | return false;
18 | }
19 | }
20 |
21 | export async function waitGanacheStarted(port: number | string, maxRetries = 1): Promise {
22 | const retry = async (retries: number) => {
23 | if (retries < maxRetries) {
24 | if (await isGanacheServer(port)) {
25 | return;
26 | }
27 | await new Promise((resolve) => setTimeout(resolve, Constants.ganacheRetryTimeout));
28 | await retry(retries + 1);
29 | } else {
30 | const error = new Error(Constants.ganacheCommandStrings.cannotStartServer);
31 | Telemetry.sendException(error);
32 | throw error;
33 | }
34 | };
35 | await retry(0);
36 | }
37 |
--------------------------------------------------------------------------------
/src/services/generic/GenericService.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import type {ChildProcess} from 'child_process';
5 | import type {OutputChannel} from 'vscode';
6 | import {Constants} from '@/Constants';
7 | import * as shell from '@/helpers/shell';
8 | import {Telemetry} from '@/Telemetry';
9 | import {UrlValidator} from '@/validators/UrlValidator';
10 | import {isGenericServer, getWeb3ClientVersion} from './GenericServiceClient';
11 |
12 | export namespace GenericService {
13 | export interface IGenericProcess {
14 | output?: OutputChannel;
15 | pid?: number;
16 | port: number | string;
17 | process?: ChildProcess;
18 | }
19 |
20 | export const genericProcesses: {[port: string]: IGenericProcess} = {};
21 |
22 | export enum PortStatus {
23 | FREE = 0,
24 | RUNNING = 1,
25 | BUSY = 2,
26 | }
27 |
28 | export async function getPortStatus(port: number | string): Promise {
29 | if (!isNaN(await shell.findPid(port))) {
30 | if (await isGenericServer(port)) {
31 | Telemetry.sendEvent('GanacheService.isGenericServerRunning.isGenericServer', {port: '' + port});
32 | return PortStatus.RUNNING;
33 | } else {
34 | Telemetry.sendEvent('GanacheService.isGenericServerRunning.portIsBusy', {port: '' + port});
35 | return PortStatus.BUSY;
36 | }
37 | }
38 |
39 | Telemetry.sendEvent('GanacheService.isGenericServerRunning.portIsFree', {port: '' + port});
40 | return PortStatus.FREE;
41 | }
42 |
43 | export async function getClientVersion(port: number | string): Promise {
44 | Telemetry.sendEvent('GenericService.checkForConnection');
45 |
46 | if (UrlValidator.validatePort(port)) {
47 | Telemetry.sendException(new Error(Constants.genericCommandStrings.invalidPort));
48 | throw new Error(`${Constants.genericCommandStrings.invalidPort}: ${port}.`);
49 | }
50 |
51 | const portStatus = await getPortStatus(port);
52 |
53 | if (portStatus === PortStatus.FREE || portStatus === PortStatus.BUSY) {
54 | Telemetry.sendException(new Error(Constants.genericCommandStrings.invalidPort));
55 | throw new Error(`${Constants.genericCommandStrings.invalidPort}: ${port}.`);
56 | }
57 |
58 | if (portStatus === PortStatus.RUNNING) {
59 | return await getWeb3ClientVersion(port);
60 | }
61 |
62 | return '';
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/services/generic/GenericServiceClient.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Constants} from '@/Constants';
5 | import {Telemetry} from '@/Telemetry';
6 | import {HttpService} from '../HttpService';
7 |
8 | export async function isGenericServer(port: number | string): Promise {
9 | try {
10 | const response = await HttpService.sendRPCRequest(
11 | `http://${Constants.localhost}:${port}`,
12 | Constants.rpcMethods.netListening
13 | );
14 | return (response && !!response.result) || false;
15 | } catch (error) {
16 | Telemetry.sendException(error as Error);
17 | return false;
18 | }
19 | }
20 |
21 | export async function getWeb3ClientVersion(port: number | string): Promise {
22 | try {
23 | const response = await HttpService.sendRPCRequest(
24 | `http://${Constants.localhost}:${port}`,
25 | Constants.rpcMethods.web3_clientVersion
26 | );
27 |
28 | return response?.result;
29 | } catch (error) {
30 | Telemetry.sendException(error as Error);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/services/infuraService/InfuraDto/ICreateProjectRequestDto.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface ICreateProjectRequestDto {
5 | name: string;
6 | private_only?: boolean;
7 | }
8 |
--------------------------------------------------------------------------------
/src/services/infuraService/InfuraDto/IInfuraEndpointDto.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface IInfuraEndpointDto {
5 | [key: string]: {
6 | https: string;
7 | wss: string;
8 | layer?: number;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/src/services/infuraService/InfuraDto/IInfuraProjectDto.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {IInfuraEndpointDto} from './IInfuraEndpointDto';
5 |
6 | export interface IInfuraProjectDto {
7 | id: string;
8 | private: string;
9 | private_only: boolean;
10 | addresses: [];
11 | origins: [];
12 | user_agents: [];
13 | name: string;
14 | status: number;
15 | created: number;
16 | updated: number;
17 | endpoints: IInfuraEndpointDto;
18 | }
19 |
--------------------------------------------------------------------------------
/src/services/infuraService/InfuraDto/IInfuraProjectQuickPick.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {IInfuraProjectDto} from '.';
5 |
6 | export interface IInfuraProjectQuickPick extends IInfuraProjectDto {
7 | label: string;
8 | picked: boolean;
9 | }
10 |
--------------------------------------------------------------------------------
/src/services/infuraService/InfuraDto/IInfuraUserDto.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export interface IInfuraUserDto {
5 | id: string;
6 | created: number;
7 | updated: number;
8 | email: string;
9 | verified: boolean;
10 | }
11 |
--------------------------------------------------------------------------------
/src/services/infuraService/InfuraDto/IProjectsResultDto.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {IInfuraProjectDto} from './IInfuraProjectDto';
5 |
6 | export interface IProjectsResultDto {
7 | allowed_projects: number;
8 | projects: IInfuraProjectDto[];
9 | }
10 |
--------------------------------------------------------------------------------
/src/services/infuraService/InfuraDto/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export * from './ICreateProjectRequestDto';
5 | export * from './IInfuraProjectDto';
6 | export * from './IInfuraUserDto';
7 | export * from './IProjectsResultDto';
8 | export * from './IInfuraEndpointDto';
9 | export * from './IInfuraProjectQuickPick';
10 |
--------------------------------------------------------------------------------
/src/validators/DialogResultValidator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Validator} from './validator';
5 |
6 | const NETWORK_NAME_RE = /[^\da-z]/g;
7 |
8 | const NETWORK_NAME_MSG = 'Invalid name. Name can contain only lowercase letters and numbers.';
9 |
10 | export namespace DialogResultValidator {
11 | export function validateConfirmationResult(result: string): string | null {
12 | const validator = new Validator(result).isNotEmpty().isConfirmationValue();
13 |
14 | return validator.getErrors();
15 | }
16 |
17 | export function validateLocalNetworkName(result: string): string | null {
18 | const validator = new Validator(result).isNotEmpty().hasNoForbiddenChar(NETWORK_NAME_RE, NETWORK_NAME_MSG);
19 |
20 | return validator.getErrors();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/validators/UrlValidator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Validator} from './validator';
5 |
6 | const PORT_RE =
7 | /^([1-9]|[1-8][0-9]|9[0-9]|[1-8][0-9]{2}|9[0-8][0-9]|99[0-9]|[1-8][0-9]{3}|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9]|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/;
8 |
9 | export const INVALID_PORT_MSG = 'Invalid port.';
10 |
11 | export namespace UrlValidator {
12 | export function validateHostUrl(url: string): string | null {
13 | const validator = new Validator(url).isNotEmpty().isUrl();
14 |
15 | return validator.getErrors();
16 | }
17 |
18 | export function validatePort(port: string | number): string | null {
19 | return `${port}`.match(PORT_RE) ? null : INVALID_PORT_MSG;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/validators/validator.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 | import {Constants} from '@/Constants';
4 |
5 | const IS_LOWER_CASE = /^[a-z0-9_\-!@$^&()+=?/<>|[\]{}:.\\~ #`*"'%;,]+$/g;
6 |
7 | export const INVALID_CONFIRMATION_RESULT = "'yes' or 'no'";
8 |
9 | export const onlyLowerCaseAllowed = 'Only lower case allowed.';
10 |
11 | export class Validator {
12 | private errors: Set = new Set();
13 |
14 | constructor(private readonly value: string) {}
15 |
16 | public getErrors(): string | null {
17 | return Array.from(this.errors).join('\r\n') || null;
18 | }
19 |
20 | public isConfirmationValue(): Validator {
21 | return this.validate((value) =>
22 | [Constants.confirmationDialogResult.yes, Constants.confirmationDialogResult.no]
23 | .map((option) => option.toLowerCase())
24 | .includes(value.toLowerCase())
25 | ? null
26 | : INVALID_CONFIRMATION_RESULT
27 | );
28 | }
29 |
30 | public isLowerCase(): Validator {
31 | return this.validate((value) => (value.search(IS_LOWER_CASE) !== -1 || !value ? null : onlyLowerCaseAllowed));
32 | }
33 |
34 | public isUrl(): Validator {
35 | return this.validate((value) =>
36 | value.search(Constants.validationRegexps.isUrl) !== -1 ? null : Constants.validationMessages.invalidHostAddress
37 | );
38 | }
39 |
40 | public hasNoForbiddenChar(forbiddenChars: RegExp, errorMessage: string): Validator {
41 | return this.validate((value) => (value.search(forbiddenChars) !== -1 ? errorMessage : null));
42 | }
43 |
44 | public isNotEmpty(): Validator {
45 | return this.validate((value) => (value.trim() ? null : Constants.validationMessages.valueCannotBeEmpty));
46 | }
47 |
48 | /**
49 | * Validates the given `value` of this `Validator` using the validation function `fn` and
50 | * appends the error if any to this `Validator`.
51 | *
52 | * The validation function should return `null` when there is no validation error.
53 | * Otherwise it should return the error message to append to this `Validator`.
54 | *
55 | * @param fn the validation function to validate this `value`.
56 | * @returns this `Validator` to use method chaining.
57 | */
58 | private validate(fn: (value: string) => string | null) {
59 | const error = fn(this.value);
60 |
61 | if (error) {
62 | this.errors.add(error);
63 | }
64 |
65 | return this;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/views/HelpView.ts:
--------------------------------------------------------------------------------
1 | import {type TreeDataProvider, type TreeItem} from 'vscode';
2 | import {OpenUrlTreeItem} from './lib/OpenUrlTreeItem';
3 |
4 | /**
5 | * Provides the links for the **Help & Feedback** Tree View.
6 | */
7 | export class HelpView implements TreeDataProvider {
8 | private readonly items: TreeItem[];
9 |
10 | constructor() {
11 | this.items = [
12 | new OpenUrlTreeItem(
13 | 'Getting Started Guide',
14 | 'https://trufflesuite.com/blog/build-on-web3-with-truffle-vs-code-extension/',
15 | 'star-full'
16 | ),
17 | new OpenUrlTreeItem('Extension Docs', 'https://trufflesuite.com/docs/vscode-ext/', 'book'),
18 | new OpenUrlTreeItem('Get Code Samples & Example Projects', 'https://trufflesuite.com/boxes/', 'package'),
19 | new OpenUrlTreeItem('Report an Issue', 'https://github.com/trufflesuite/vscode-ext/issues/new', 'report'),
20 | new OpenUrlTreeItem('Community and Support', 'https://trufflesuite.com/community/', 'organization'),
21 | ];
22 | }
23 |
24 | getTreeItem(element: TreeItem): TreeItem {
25 | return element;
26 | }
27 |
28 | getChildren(_element?: TreeItem): TreeItem[] {
29 | return this.items;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/views/lib/OpenUrlTreeItem.ts:
--------------------------------------------------------------------------------
1 | import {env, ThemeIcon, TreeItem, Uri, window} from 'vscode';
2 |
3 | /**
4 | * This class enhances the `TreeItem` to support links when selected.
5 | */
6 | export class OpenUrlTreeItem extends TreeItem {
7 | /**
8 | * Creates a new `OpenUrlTreeItem `.
9 | *
10 | * @param label the visible label of this `TreeItem`.
11 | * @param url the URL to open when this `TreeItem` is selected.
12 | * @param iconPath the icon path id to use for this `TreeItem`.
13 | */
14 | constructor(label: string, private readonly url: string | undefined, iconPath?: string) {
15 | super(label);
16 | this.command = {title: '', command: 'truffle-vscode.openUrl', arguments: [this]};
17 | this.iconPath = new ThemeIcon(iconPath ?? 'globe');
18 | }
19 |
20 | /**
21 | * Opens `url` externally using the default application.
22 | */
23 | public async openUrl(): Promise {
24 | if (this.url) {
25 | await env.openExternal(Uri.parse(this.url));
26 | } else {
27 | void window.showWarningMessage(`URL was blank for item: ${this.label}`);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test/FakeExtensionState.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {Memento} from 'vscode';
5 |
6 | export class FakeExtensionState implements Memento {
7 | constructor(private dict: {[id: string]: any} = {}) {}
8 | keys(): readonly string[] {
9 | return Object.keys(this.dict);
10 | }
11 |
12 | public get(key: string): T | undefined {
13 | return this.dict[key] as T;
14 | }
15 |
16 | public update(key: string, value: any): Thenable {
17 | return (this.dict[key] = value);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/TestConstants.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export class TestConstants {
5 | public static testError = 'TestError';
6 |
7 | public static testMnemonic = 'test test test test test test test test test test test test';
8 |
9 | public static servicesNames = {
10 | development: 'development',
11 | localProject: 'LocalProject',
12 | testNetwork: 'testNetwork',
13 | };
14 |
15 | public static networkNames = {
16 | local: 'development',
17 | };
18 |
19 | public static truffleCommandTestDataFolder = 'testData';
20 | }
21 |
--------------------------------------------------------------------------------
/test/TreeManager.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import assert from 'assert';
5 | import rewire from 'rewire';
6 |
7 | describe('TreeManager tests', () => {
8 | const numberOfElements = 3;
9 | it(`fillDefaultTypes should return array with ${numberOfElements} elements`, async () => {
10 | // Arrange
11 | const treeManagerRewire = rewire('../src/services/tree/TreeManager');
12 |
13 | // Act
14 | const result = treeManagerRewire.TreeManager.__proto__.fillDefaultTypes([]);
15 |
16 | // Assert
17 | assert.strictEqual(
18 | result.length,
19 | numberOfElements,
20 | `fillDefaultTypes count should be equal to ${numberOfElements}`
21 | );
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/test/TruffleCommandsTests/telemetry.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {mapNetworkName} from '@/commands/TruffleCommands';
5 | import assert from 'assert';
6 | import uuid from 'uuid';
7 |
8 | describe('Telemetry helper test', () => {
9 | [
10 | {
11 | expectedResult: 'loc',
12 | name: 'development',
13 | },
14 | {
15 | expectedResult: 'inf',
16 | name: `inf_${uuid.v4()}`,
17 | },
18 | {
19 | expectedResult: 'loc',
20 | name: `loc_${uuid.v4()}`,
21 | },
22 | {
23 | expectedResult: 'other',
24 | name: `${uuid.v4()}`,
25 | },
26 | ].forEach((network) => {
27 | it(`mapNetworkName should return correct result for network '${network.name}'`, () => {
28 | // Act
29 | const result = mapNetworkName(network.name);
30 |
31 | // Assert
32 | assert.strictEqual(result, network.expectedResult);
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/test/TruffleCommandsTests/testData/TestContract.json:
--------------------------------------------------------------------------------
1 | {
2 | "contractName": "HelloBlockchain",
3 | "abi": [
4 | {
5 | "constant": true,
6 | "inputs": [],
7 | "name": "ResponseMessage",
8 | "outputs": [
9 | {
10 | "name": "",
11 | "type": "string"
12 | }
13 | ],
14 | "payable": false,
15 | "stateMutability": "view",
16 | "type": "function"
17 | },
18 | {
19 | "constant": true,
20 | "inputs": [],
21 | "name": "Responder",
22 | "outputs": [
23 | {
24 | "name": "",
25 | "type": "address"
26 | }
27 | ],
28 | "payable": false,
29 | "stateMutability": "view",
30 | "type": "function"
31 | },
32 | {
33 | "constant": true,
34 | "inputs": [],
35 | "name": "RequestMessage",
36 | "outputs": [
37 | {
38 | "name": "",
39 | "type": "string"
40 | }
41 | ],
42 | "payable": false,
43 | "stateMutability": "view",
44 | "type": "function"
45 | }
46 | ],
47 | "bytecode": "0x00000000000000000000000000000000",
48 | "deployedBytecode": "0x00000000000000000000000000000000",
49 | "compiler": {
50 | "name": "solc",
51 | "version": "0.5.0+commit.1d4f565a.Emscripten.clang"
52 | },
53 | "schemaVersion": "3.0.9",
54 | "devdoc": {
55 | "methods": {}
56 | },
57 | "userdoc": {
58 | "methods": {}
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/test/TruffleCommandsTests/testData/truffle-config.js:
--------------------------------------------------------------------------------
1 | // const HDWalletProvider = require('@truffle/hdwallet-provider');
2 | // const path = require('path');
3 | // const fs = require('fs');
4 | module.exports = {
5 | networks: {},
6 | mocha: {},
7 | compilers: {
8 | solc: {},
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/test/TruffleExtensionAdapter.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import assert from 'assert';
5 | import sinon from 'sinon';
6 | import {TruffleCommands} from '../src/commands/TruffleCommands';
7 | import {TruffleExtensionAdapter} from '../src/services/extensionAdapter';
8 |
9 | describe('TruffleExtensionAdapter', () => {
10 | let buildContractsMock: sinon.SinonStub;
11 | let deployContractsMock: sinon.SinonStub;
12 | let truffleExtensionAdapter: TruffleExtensionAdapter;
13 |
14 | beforeEach(() => {
15 | buildContractsMock = sinon.stub(TruffleCommands, 'buildContracts');
16 | deployContractsMock = sinon.stub(TruffleCommands, 'deployContracts');
17 |
18 | truffleExtensionAdapter = new TruffleExtensionAdapter();
19 | });
20 |
21 | afterEach(() => {
22 | sinon.restore();
23 | });
24 |
25 | it('build method should call truffleCommands.buildContracts', async () => {
26 | // Act
27 | await truffleExtensionAdapter.build();
28 |
29 | // Assert
30 | assert.strictEqual(buildContractsMock.calledOnce, true, 'TruffleCommands.buildContracts should be called once');
31 | });
32 |
33 | it('deploy method should call truffleCommands.buildContracts', async () => {
34 | // Act
35 | await truffleExtensionAdapter.deploy();
36 |
37 | // Assert
38 | assert.strictEqual(deployContractsMock.calledOnce, true, 'TruffleCommands.deployContracts should be called once');
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/test/commands/ServiceCommands/createService.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import assert from 'assert';
5 | import rewire from 'rewire';
6 | import sinon from 'sinon';
7 | import uuid from 'uuid';
8 | import {QuickPickOptions} from 'vscode';
9 | import {Constants} from '@/Constants';
10 | import * as userInteraction from '@/helpers/userInteraction';
11 | import {ItemType} from '@/Models/ItemType';
12 | import {LocalProject, TLocalProjectOptions} from '@/Models/TreeItems/LocalProject';
13 | import {LocalService} from '@/Models/TreeItems/LocalService';
14 | import {TreeManager} from '@/services/tree/TreeManager';
15 |
16 | const description = '';
17 |
18 | const options: TLocalProjectOptions = {
19 | isForked: false,
20 | forkedNetwork: '',
21 | blockNumber: 0,
22 | url: '',
23 | };
24 |
25 | describe('Create Service', () => {
26 | afterEach(() => {
27 | sinon.restore();
28 | });
29 |
30 | it('showQuickPick should be executed with Constants.placeholders.selectDestination placeholder', async () => {
31 | // Arrange
32 | const serviceCommandsRewire = rewire('../../../src/commands/ServiceCommands');
33 | const showQuickPickStub = sinon.stub();
34 | showQuickPickStub.returns({
35 | cmd: sinon.mock().returns(new LocalProject(uuid.v4(), 1234, options, description)),
36 | itemType: ItemType.LOCAL_PROJECT,
37 | label: Constants.treeItemData.service.local.label,
38 | });
39 |
40 | sinon.stub(TreeManager, 'getItem').returns(new LocalService());
41 | sinon.replace(userInteraction, 'showQuickPick', showQuickPickStub);
42 |
43 | // Act
44 | await serviceCommandsRewire.ServiceCommands.createProject();
45 |
46 | // Assert
47 | assert.strictEqual(
48 | (showQuickPickStub.getCall(0).args[1] as QuickPickOptions).placeHolder,
49 | `${Constants.placeholders.selectDestination}.`,
50 | 'showQuickPick should be called with given arguments'
51 | );
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/test/commands/ServiceCommands/disconnecNetwork.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import assert from 'assert';
5 | import rewire from 'rewire';
6 | import sinon from 'sinon';
7 | import {LocalProject, type TLocalProjectOptions} from '@/Models/TreeItems/LocalProject';
8 | import {GanacheService} from '@/services/ganache/GanacheService';
9 | import {TreeManager} from '@/services/tree/TreeManager';
10 | import {ProjectView} from '@/views/NetworksView';
11 |
12 | const description = '';
13 |
14 | const options: TLocalProjectOptions = {
15 | isForked: false,
16 | forkedNetwork: '',
17 | blockNumber: 0,
18 | url: '',
19 | };
20 |
21 | describe('Disconnect Service', () => {
22 | afterEach(() => {
23 | sinon.restore();
24 | });
25 |
26 | describe('DisconnectProject_ShouldStopGanacheServer_LocalProject', () => {
27 | const services = [{localProjectInstance: new LocalProject('name', 8545, options, description), executed: true}];
28 |
29 | services.forEach(async (service) => {
30 | it('GanacheService.stopGanacheServer() should be executed only for LocalProject.', async () => {
31 | // Arrange
32 | const serviceCommandsRewire = rewire('../../../src/commands/ServiceCommands');
33 | const projectView = new ProjectView(service.localProjectInstance);
34 | const stopGanacheServerStub = sinon.stub(GanacheService, 'stopGanacheServer');
35 |
36 | // Act
37 | await serviceCommandsRewire.ServiceCommands.disconnectProject(projectView);
38 |
39 | // Assert
40 | assert.strictEqual(
41 | stopGanacheServerStub.calledOnce,
42 | service.executed,
43 | 'stopGanacheServer should be called once when service.executed'
44 | );
45 | });
46 | });
47 | });
48 |
49 | describe('DisconnectProject_ShouldRemoveItem', () => {
50 | it('treeManager.removeItem() should be executed for LocalProject.', async () => {
51 | // Arrange
52 | const serviceCommandsRewire = rewire('../../../src/commands/ServiceCommands');
53 | const projectView = new ProjectView(new LocalProject('name', 8545, options, description));
54 | const removeItemMock = sinon.stub(TreeManager, 'removeItem').returns(undefined);
55 |
56 | // Act
57 | await serviceCommandsRewire.ServiceCommands.disconnectProject(projectView);
58 |
59 | // Assert
60 | assert.strictEqual(removeItemMock.calledOnce, true, 'removeItem should be called once');
61 | });
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/test/commands/ServiceCommands/telemetry.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import assert from 'assert';
5 | import {ItemType} from '@/Models/ItemType';
6 | import {mapItemType} from '@/commands/ServiceCommands';
7 |
8 | describe('ServiceCommands - Telemetry helper test', () => {
9 | [
10 | {
11 | expectedResult: 'loc',
12 | itemType: ItemType.LOCAL_PROJECT,
13 | },
14 | {
15 | expectedResult: 'inf',
16 | itemType: ItemType.INFURA_PROJECT,
17 | },
18 | {
19 | expectedResult: 'other',
20 | itemType: ItemType.MEMBER,
21 | },
22 | ].forEach((testItemType) => {
23 | it(`mapNetworkName should return correct result for network type '${testItemType.expectedResult}'`, () => {
24 | // Act
25 | const result = mapItemType(testItemType.itemType);
26 |
27 | // Assert
28 | assert.strictEqual(result, testItemType.expectedResult);
29 | });
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/test/debugAdapter/SolidityDebugSessionClient.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {SolidityDebugSession} from '../../src/debugAdapter/debugSession';
5 |
6 | const baseDebugAdapterResponseMock = {request_seq: 1, success: true, command: '', seq: 1, type: ''};
7 |
8 | export class SolidityDebugSessionClient extends SolidityDebugSession {
9 | public execProtectedLaunchRequest() {
10 | const mockArgs = {txHash: '0x', workingDirectory: '/path', files: [], providerUrl: 'http://127.0.0.1:8545'};
11 | return this.launchRequest(baseDebugAdapterResponseMock, mockArgs);
12 | }
13 |
14 | public execProtectedSetBreakPointsRequest() {
15 | const mockSetBreakPointsResponse = {body: {breakpoints: []}, ...baseDebugAdapterResponseMock};
16 | const mockArgs = {source: {}};
17 | return this.setBreakPointsRequest(mockSetBreakPointsResponse, mockArgs);
18 | }
19 |
20 | public execProtectedThreadRequest() {
21 | const mockThreadsResponse = {body: {threads: []}, ...baseDebugAdapterResponseMock};
22 | return this.threadsRequest(mockThreadsResponse);
23 | }
24 |
25 | public execProtectedStackTraceRequest() {
26 | const mockStackTraceResponse = {body: {stackFrames: []}, ...baseDebugAdapterResponseMock};
27 | return this.stackTraceRequest(mockStackTraceResponse);
28 | }
29 |
30 | public execProtectedCustomRequest(command: string) {
31 | return this.customRequest(command, baseDebugAdapterResponseMock);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/debugAdapter/web3Wrapper.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import truffleProvider from '@truffle/provider';
5 | import assert from 'assert';
6 | import {restore, stub} from 'sinon';
7 | import {INetworkOption} from '@/helpers/ConfigurationReader';
8 | import {Web3Wrapper} from '@/debugAdapter/web3Wrapper';
9 |
10 | describe('Web3Wrapper unit tests', () => {
11 | afterEach(() => {
12 | restore();
13 | });
14 |
15 | it('getProvider should call truffleProvider.create', () => {
16 | // Arrange
17 | const networkOptionsMock: INetworkOption = {
18 | host: '127.0.0.1',
19 | network_id: '*',
20 | port: 8545,
21 | };
22 | const truffleProviderCreateStub = stub(truffleProvider, 'create').returns({});
23 |
24 | // Act
25 | const web3Wrapper = new Web3Wrapper(networkOptionsMock);
26 | web3Wrapper.getProvider();
27 |
28 | assert.strictEqual(truffleProviderCreateStub.called, true, 'truffleProvider.create should be called');
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/test/runTest.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 |
3 | import {runTests} from '@vscode/test-electron';
4 |
5 | async function main() {
6 | try {
7 | const extensionDevelopmentPath = path.resolve(__dirname, '../../');
8 | const extensionTestsPath = path.resolve(__dirname);
9 |
10 | await runTests({extensionDevelopmentPath, extensionTestsPath});
11 | } catch (err) {
12 | console.error('Failed to run tests');
13 | process.exit(1);
14 | }
15 | }
16 |
17 | main();
18 |
--------------------------------------------------------------------------------
/test/testData/enumTestContract.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.0;
2 | pragma experimental ABIEncoderV2;
3 |
4 | contract Base {
5 | address public Requestor;
6 | address public Responder;
7 | }
8 |
9 | contract HelloBlockchain is Base {
10 | enum StateType {
11 | Request,
12 | Respond
13 | }
14 | enum SwitcherEnum {
15 | On,
16 | Off
17 | }
18 |
19 | StateType public State;
20 | SwitcherEnum public Flag;
21 | string public RequestMessage;
22 | string public ResponseMessage;
23 |
24 | constructor(string memory message) public {
25 | Requestor = msg.sender;
26 | RequestMessage = message;
27 | State = StateType.Request;
28 | }
29 |
30 | function SendRequest(string memory requestMessage, StateType state) public {
31 | RequestMessage = requestMessage;
32 | State = state;
33 | }
34 |
35 | function SendResponse(StateType state, SwitcherEnum flag) public {
36 | if (flag == SwitcherEnum.On) {
37 | Responder = msg.sender;
38 | }
39 |
40 | State = state;
41 | }
42 |
43 | function SwitcheToOff(uint256 completed) public {
44 | if (completed > 0) {
45 | Flag = SwitcherEnum.Off;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/test/testData/truffleConfigTestdata.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import fs from 'fs-extra';
5 | import path from 'path';
6 |
7 | export const referenceMnemonic = 'some menmonic some menmonic some menmonic some menmonic some menmonic some menmonic';
8 |
9 | export const referenceCfgContent =
10 | 'const HDWalletProvider = require("truffle-hdwallet-provider");' +
11 | 'module.exports = {' +
12 | ' networks: {' +
13 | ' development: {' +
14 | ' host: "127.0.0.1",' +
15 | ' port: 8545,' +
16 | ' network_id: "*"' +
17 | ' },' +
18 | ' "localhost:123": {' +
19 | ' from: "string",' +
20 | ' gasPrice: 3,' +
21 | ' host: "127.0.0.1",' +
22 | ' network_id: "*",' +
23 | ' port: 123,' +
24 | ' provider: new HDWalletProvider(' +
25 | ' fs.readFileSync("path", "encoding"),' +
26 | ' "url"),' +
27 | ' skipDryRun: true,' +
28 | ' timeoutBlocks: 4,' +
29 | ' websockets: false,' +
30 | ' }' +
31 | ' },' +
32 | ' mocha: {},' +
33 | ' compilers: {' +
34 | ' solc: {}' +
35 | ' }' +
36 | '};';
37 |
38 | export const referenceConfiguration = {
39 | contracts_build_directory: 'build\\contracts',
40 | contracts_directory: 'contracts',
41 | migrations_directory: 'migrations',
42 | networks: [
43 | {
44 | name: 'development',
45 | options: {
46 | host: '127.0.0.1',
47 | network_id: '*',
48 | port: 8545,
49 | },
50 | },
51 | {
52 | name: 'localhost:123',
53 | options: {
54 | from: 'string',
55 | gasPrice: 3,
56 | host: '127.0.0.1',
57 | network_id: '*',
58 | port: 123,
59 | provider: {
60 | mnemonic: referenceMnemonic,
61 | raw: 'new HDWalletProvider(fs.readFileSync("path", "encoding"), "url")',
62 | url: 'url',
63 | },
64 | skipDryRun: true,
65 | timeoutBlocks: 4,
66 | websockets: false,
67 | },
68 | },
69 | ],
70 | provider: {
71 | host: 'localhost',
72 | },
73 | network_id: 1,
74 | };
75 |
76 | const referenceAstPath = path.join(__dirname, 'referenceAstObject.json');
77 | export const referenceAstObject = JSON.parse(fs.readFileSync(referenceAstPath, 'utf-8').toString());
78 |
--------------------------------------------------------------------------------
/test/testHelpers/Random.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | export function getRandomInt(max: number) {
5 | return Math.floor(Math.random() * Math.floor(max));
6 | }
7 |
--------------------------------------------------------------------------------
/test/validators/DialogResultValidator.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Consensys Software Inc. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | import {INVALID_CONFIRMATION_RESULT} from '@/validators/validator';
5 | import assert from 'assert';
6 | import {Constants} from '@/Constants';
7 | import {DialogResultValidator} from '@/validators/DialogResultValidator';
8 | import {TEST_DIALOG_ANSWERS} from './test-dialog-answers';
9 |
10 | describe('validators::DialogResultValidator', () => {
11 | describe('Unit test', () => {
12 | describe('validateConfirmationResult', () => {
13 | it('should fail when result is empty', () => {
14 | // Arrange
15 | const testString = '';
16 |
17 | // Act
18 | const result = DialogResultValidator.validateConfirmationResult(testString) as string;
19 |
20 | // Assert
21 | assert.strictEqual(
22 | result.includes(Constants.validationMessages.valueCannotBeEmpty),
23 | true,
24 | `validation result should include message "${Constants.validationMessages.valueCannotBeEmpty}"`
25 | );
26 | assert.strictEqual(
27 | result.includes(INVALID_CONFIRMATION_RESULT),
28 | true,
29 | `validation result should include message "${INVALID_CONFIRMATION_RESULT}"`
30 | );
31 | });
32 |
33 | it('should fail when result different from yes or no', () => {
34 | // Arrange
35 | const testString = 'some string';
36 |
37 | // Act
38 | const result = DialogResultValidator.validateConfirmationResult(testString) as string;
39 |
40 | // Assert
41 | assert.strictEqual(
42 | result.includes(INVALID_CONFIRMATION_RESULT),
43 | true,
44 | `validation result should include message "${INVALID_CONFIRMATION_RESULT}"`
45 | );
46 | });
47 |
48 | TEST_DIALOG_ANSWERS.forEach((answer) => {
49 | it(`should pass when answer is ${answer}`, () => {
50 | // Act
51 | const result = DialogResultValidator.validateConfirmationResult(answer);
52 |
53 | // Assert
54 | assert.strictEqual(result, null, 'validation result should be null');
55 | });
56 | });
57 | });
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/test/validators/test-dialog-answers.ts:
--------------------------------------------------------------------------------
1 | export const TEST_DIALOG_ANSWERS = ['yes', 'YES', 'Yes', 'YEs', 'YeS', 'yES', 'yEs', 'yeS', 'no', 'NO', 'No', 'nO'];
2 |
--------------------------------------------------------------------------------
/test/vscode-register.ts:
--------------------------------------------------------------------------------
1 | import mockery from 'mockery';
2 | import * as vscode from './vscode';
3 |
4 | // This option is used to omit `WARNING: loading non-allowed module` log message.
5 | //
6 | // https://github.com/mfncooper/mockery/issues/27
7 | mockery.enable({warnOnUnregistered: false});
8 |
9 | // We use `mockery`[1] to provide a drop-in replacement for `vscode` module.
10 | // The `vscode` module is not available when running `mocha` from the command line.
11 | //
12 | // We replace the original `vscode` with `test/vscode.ts`.
13 | // `test/vscode.ts` provides just the minimal definitions needed to run our tests.
14 | // Most of the definitions need no implementation, not even the proper signature,
15 | // since the tests themselves mock them using `sinon`.
16 | //
17 | // This is inspired by [2].
18 | // `mockery` is the equivalent of `jest.mock`.
19 | //
20 | // [1] https://github.com/mfncooper/mockery#enabling-mockery
21 | // [2] https://github.com/mhutchie/vscode-git-graph/blob/d7f43f429a9e024e896bac9fc65fdc530935c812/tests/commands.test.ts#L3
22 | mockery.registerMock('vscode', vscode);
23 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es6",
5 | "outDir": "out",
6 | "lib": ["es6"],
7 | "sourceMap": true,
8 | "resolveJsonModule": true,
9 | "baseUrl": "./",
10 | "paths": {
11 | "@/*": ["./src/*"]
12 | },
13 | // Note: To transform paths for both the output .js and .d.ts files, you need both of the below entries
14 | "plugins": [
15 | // Transform paths in output .js files
16 | {
17 | "transform": "typescript-transform-paths",
18 | "exclude": ["**/node_modules/**"]
19 | },
20 | // Transform paths in output .d.ts files (Include this line if you output declarations files)
21 | {
22 | "transform": "typescript-transform-paths",
23 | "afterDeclarations": true,
24 | "exclude": ["**/node_modules/**"]
25 | }
26 | ],
27 | "rootDir": ".",
28 | "strict": true,
29 | /* Additional Checks */
30 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
31 | "esModuleInterop": true,
32 | "noUnusedLocals": true,
33 | "noImplicitThis": true,
34 | "noImplicitReturns": true,
35 | "strictNullChecks": true,
36 | "noUnusedParameters": true,
37 | "allowJs": true,
38 | "checkJs": false,
39 | "skipLibCheck": true,
40 | "typeRoots": ["./node_modules/@types", "./node_modules/@machinomy", "./src/debugger/types"]
41 | },
42 | "include": [
43 | ".eslintrc.js",
44 | "src/**/*.js",
45 | "src/**/*.ts",
46 | "src/**/*.json",
47 | "test/**/*.js",
48 | "test/**/*.ts",
49 | "test/**/*.json"
50 | ],
51 | "exclude": ["node_modules", ".vscode-test", "drizzleUI", "ui-test"],
52 |
53 | // In order for `ts-node`[1] to load `.d.ts` definitions,
54 | // we need to explicitly enable the `files`[2] option.
55 | //
56 | // We use `.d.ts` definitions to declare variables outside `src/`,
57 | // for instance `IS_BUILD_TIME` from `webpack.common.js`.
58 | //
59 | // Since we invoke `ts-node` from `.mocharc.js`,
60 | // we need to enable this option here.
61 | //
62 | // [1] https://typestrong.org/ts-node/docs/configuration/#via-tsconfigjson-recommended
63 | // [2] https://typestrong.org/ts-node/docs/options#files
64 | "ts-node": {
65 | "files": true
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const {merge} = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 |
4 | module.exports = merge(common, {
5 | mode: 'development',
6 | devtool: 'inline-source-map',
7 | });
8 |
--------------------------------------------------------------------------------
/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const {merge} = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 |
4 | module.exports = merge(common, {
5 | mode: 'production',
6 | // By removing source map generation, we reduce bundle size by 50%.
7 | // See https://webpack.js.org/configuration/devtool/ for more details.
8 | devtool: false,
9 | optimization: {
10 | minimize: true,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------