├── .editorconfig ├── .gitattributes ├── .github ├── actionlint.yaml ├── actions │ └── replace-version │ │ ├── action.yml │ │ ├── dist │ │ ├── index.js │ │ └── package.json │ │ ├── index.js │ │ ├── package-lock.json │ │ └── package.json ├── release-please │ ├── config-backport.json │ ├── config.json │ └── manifest.json ├── renovate.json └── workflows │ ├── docs.yml │ ├── e2e.yml │ ├── install-test.yml │ ├── lint.yml │ ├── pack.yml │ ├── promote.yml │ ├── release.yml │ ├── run-tests.yml │ ├── snapshot.yml │ └── tests.yml ├── .gitignore ├── .prettierignore ├── .vscode ├── extensions.json └── settings.json ├── .yarn └── releases │ └── yarn-4.5.0.cjs ├── .yarnrc.yml ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── install.sh ├── package.json ├── packages ├── cli-connector │ ├── .gitignore │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── App.tsx │ │ ├── index.css │ │ ├── main.tsx │ │ ├── reset.d.ts │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── cli │ ├── package.json │ └── package │ │ ├── .gitignore │ │ ├── .yarn │ │ ├── patches │ │ │ ├── oclif-npm-4.15.9-f51cd140c1.patch │ │ │ └── oclif-patch-c5b232dd7e.patch │ │ └── releases │ │ │ └── yarn-4.5.0.cjs │ │ ├── .yarnrc.yml │ │ ├── CHANGELOG.md │ │ ├── bin │ │ ├── dev.js │ │ ├── run.cmd │ │ └── run.js │ │ ├── docs │ │ ├── commands │ │ │ └── README.md │ │ └── configs │ │ │ ├── README.md │ │ │ ├── config.md │ │ │ ├── env.md │ │ │ ├── provider-artifacts.md │ │ │ ├── provider-secrets.md │ │ │ └── provider.md │ │ ├── eslint.config.js │ │ ├── example.env │ │ ├── nsis │ │ ├── Plugins │ │ │ ├── amd64-unicode │ │ │ │ └── EnVar.dll │ │ │ ├── x86-ansi │ │ │ │ └── EnVar.dll │ │ │ └── x86-unicode │ │ │ │ └── EnVar.dll │ │ ├── custom-installer.nsi │ │ └── include │ │ │ └── .gitkeep │ │ ├── package.json │ │ ├── resources │ │ └── license-header.js │ │ ├── src │ │ ├── baseCommand.ts │ │ ├── beforeBuild.ts │ │ ├── commands │ │ │ ├── chain │ │ │ │ └── info.ts │ │ │ ├── default │ │ │ │ └── env.ts │ │ │ ├── local │ │ │ │ ├── down.ts │ │ │ │ ├── init.ts │ │ │ │ ├── logs.ts │ │ │ │ ├── ps.ts │ │ │ │ └── up.ts │ │ │ └── provider │ │ │ │ ├── cc-activate.ts │ │ │ │ ├── cc-create.ts │ │ │ │ ├── cc-finish.ts │ │ │ │ ├── cc-info.ts │ │ │ │ ├── cc-remove.ts │ │ │ │ ├── cc-rewards-withdraw.ts │ │ │ │ ├── deal-exit.ts │ │ │ │ ├── deal-list.ts │ │ │ │ ├── deal-rewards-info.ts │ │ │ │ ├── deal-rewards-withdraw.ts │ │ │ │ ├── deploy.ts │ │ │ │ ├── gen.ts │ │ │ │ ├── info.ts │ │ │ │ ├── init.ts │ │ │ │ ├── offer-create.ts │ │ │ │ ├── offer-info.ts │ │ │ │ ├── offer-remove.ts │ │ │ │ ├── offer-update.ts │ │ │ │ ├── register.ts │ │ │ │ ├── tokens-distribute.ts │ │ │ │ ├── tokens-withdraw.ts │ │ │ │ └── update.ts │ │ ├── environment.d.ts │ │ ├── errorInterceptor.js │ │ ├── genConfigDocs.ts │ │ ├── genGqlSchema.ts │ │ ├── index.ts │ │ ├── lib │ │ │ ├── ajvInstance.ts │ │ │ ├── chain │ │ │ │ ├── chainConfig.ts │ │ │ │ ├── chainValidators.ts │ │ │ │ ├── commitment.ts │ │ │ │ ├── conversions.ts │ │ │ │ ├── currencies.ts │ │ │ │ ├── depositCollateral.ts │ │ │ │ ├── distributeToNox.ts │ │ │ │ ├── offer │ │ │ │ │ ├── offer.ts │ │ │ │ │ └── updateOffers.ts │ │ │ │ └── providerInfo.ts │ │ │ ├── chainFlags.ts │ │ │ ├── commandObj.ts │ │ │ ├── configs │ │ │ │ ├── initConfigNew.ts │ │ │ │ ├── initConfigNewTypes.ts │ │ │ │ ├── project │ │ │ │ │ ├── chainContainers.ts │ │ │ │ │ ├── dockerCompose.ts │ │ │ │ │ ├── env │ │ │ │ │ │ ├── env.ts │ │ │ │ │ │ ├── env0.ts │ │ │ │ │ │ ├── env1.ts │ │ │ │ │ │ └── env2.ts │ │ │ │ │ ├── provider │ │ │ │ │ │ ├── provider.ts │ │ │ │ │ │ ├── provider0.ts │ │ │ │ │ │ ├── provider1.ts │ │ │ │ │ │ ├── provider2.ts │ │ │ │ │ │ ├── provider3.ts │ │ │ │ │ │ └── provider4.ts │ │ │ │ │ ├── providerArtifacts │ │ │ │ │ │ ├── providerArtifacts.ts │ │ │ │ │ │ ├── providerArtifacts0.ts │ │ │ │ │ │ ├── providerArtifacts1.ts │ │ │ │ │ │ ├── providerArtifacts2.ts │ │ │ │ │ │ └── providerArtifacts3.ts │ │ │ │ │ └── providerSecrets │ │ │ │ │ │ ├── providerSecrets.ts │ │ │ │ │ │ └── providerSecrets0.ts │ │ │ │ └── user │ │ │ │ │ └── config │ │ │ │ │ ├── config.ts │ │ │ │ │ ├── config0.ts │ │ │ │ │ └── config1.ts │ │ │ ├── const.ts │ │ │ ├── countly.ts │ │ │ ├── dbg.ts │ │ │ ├── dealClient.ts │ │ │ ├── dockerCompose.ts │ │ │ ├── ensureChainNetwork.ts │ │ │ ├── execPromise.ts │ │ │ ├── fluenceEnvPrompt.ts │ │ │ ├── generateUserProviderConfig.ts │ │ │ ├── gql │ │ │ │ ├── gql.ts │ │ │ │ ├── gqlCodegen.ts │ │ │ │ └── schema.graphql │ │ │ ├── helpers │ │ │ │ ├── aliasesText.ts │ │ │ │ ├── bigintOps.ts │ │ │ │ ├── getIsInteractive.ts │ │ │ │ ├── getPeerIdFromSecretKey.ts │ │ │ │ ├── logAndFail.ts │ │ │ │ ├── recursivelyFindFile.ts │ │ │ │ ├── setTryTimeout.ts │ │ │ │ ├── spinner.ts │ │ │ │ ├── stringifyUnknown.ts │ │ │ │ ├── typesafeStringify.ts │ │ │ │ ├── utils.ts │ │ │ │ └── validations.ts │ │ │ ├── keyPairs.ts │ │ │ ├── lifeCycle.ts │ │ │ ├── manifestsDeploy.ts │ │ │ ├── manifestsGen.ts │ │ │ ├── paths.ts │ │ │ ├── prompt.ts │ │ │ ├── resolveComputePeersByNames.ts │ │ │ ├── resolveFluenceEnv.ts │ │ │ ├── server.ts │ │ │ ├── setupEnvironment.ts │ │ │ └── typeHelpers.ts │ │ ├── reset.d.ts │ │ ├── types.d.ts │ │ ├── versions.json │ │ └── versions.ts │ │ ├── test │ │ ├── helpers │ │ │ ├── commonWithSetupTests.ts │ │ │ ├── constants.ts │ │ │ ├── paths.ts │ │ │ ├── sharedSteps.ts │ │ │ └── utils.ts │ │ ├── setup │ │ │ ├── generateTemplates.ts │ │ │ └── localUp.ts │ │ ├── tests │ │ │ └── provider.test.ts │ │ └── tsconfig.json │ │ ├── tmp │ │ └── cache │ │ │ └── 22.10.0 │ │ │ └── SHASUMS256.txt.asc │ │ ├── tsconfig.eslint.json │ │ ├── tsconfig.json │ │ ├── vitest.config.ts │ │ └── yarn.lock ├── common │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── reset.d.ts │ └── tsconfig.json └── eslint-config │ ├── README.md │ ├── common.js │ ├── license-header.js │ ├── node.js │ ├── package.json │ └── react.js ├── rename-packed.js ├── turbo.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | max_line_length = 80 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | indent_size = 4 15 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /.yarn/** linguist-vendored 2 | /.yarn/releases/* binary 3 | /.yarn/plugins/**/* binary 4 | /.pnp.* binary linguist-generated 5 | -------------------------------------------------------------------------------- /.github/actionlint.yaml: -------------------------------------------------------------------------------- 1 | self-hosted-runner: 2 | labels: 3 | - builder 4 | - linux-amd64-m-xlarge 5 | - linux-arm64-m-xlarge 6 | - linux-amd64-m-2xlarge 7 | - linux-arm64-m-2xlarge 8 | - linux-amd64-c-2xlarge 9 | - linux-arm64-c-2xlarge 10 | -------------------------------------------------------------------------------- /.github/actions/replace-version/action.yml: -------------------------------------------------------------------------------- 1 | name: Replace version 2 | description: | 3 | Replace version in packages/cli/package/src/versions.json 4 | 5 | inputs: 6 | versions: 7 | type: string 8 | 9 | runs: 10 | using: "node20" 11 | main: "dist/index.js" 12 | -------------------------------------------------------------------------------- /.github/actions/replace-version/dist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /.github/actions/replace-version/index.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { exportVariable, getInput, setFailed } from "@actions/core"; 3 | import { readFileSync, writeFileSync } from "fs"; 4 | import { join } from "path"; 5 | import assert from "assert"; 6 | 7 | try { 8 | const inputVersions = JSON.parse(getInput("versions")); 9 | assert(typeof inputVersions === "object" && inputVersions !== null); 10 | 11 | assert( 12 | typeof process.env.GITHUB_WORKSPACE === "string", 13 | "GITHUB_WORKSPACE environment variable is not set", 14 | ); 15 | 16 | const versionsFilePath = join( 17 | process.env.GITHUB_WORKSPACE, 18 | "packages", 19 | "cli", 20 | "package", 21 | "src", 22 | "versions.json", 23 | ); 24 | 25 | const versionsFileContent = readFileSync(versionsFilePath, "utf-8"); 26 | const versions = JSON.parse(versionsFileContent); 27 | assert(typeof versions === "object" && versions !== null); 28 | 29 | let cargoDependencyUpdated = false; 30 | 31 | // Merge inputVersions into versions 32 | for (const category in inputVersions) { 33 | if ( 34 | !versions.hasOwnProperty(category) || 35 | inputVersions[category] === null 36 | ) { 37 | continue; 38 | } 39 | 40 | const inputCategoryValue = inputVersions[category]; 41 | if ( 42 | typeof inputCategoryValue === "string" || 43 | typeof inputCategoryValue === "number" 44 | ) { 45 | if (inputCategoryValue !== "null") { 46 | // ignore "null" strings 47 | versions[category] = inputCategoryValue; 48 | } 49 | } else if (typeof inputCategoryValue === "object") { 50 | for (const component in inputCategoryValue) { 51 | if ( 52 | !versions[category].hasOwnProperty(component) || 53 | inputVersions[category][component] === null || 54 | inputVersions[category][component] === "null" // ignore "null" strings 55 | ) { 56 | continue; 57 | } 58 | 59 | versions[category][component] = inputVersions[category][component]; 60 | 61 | // Check if a cargo dependency was updated 62 | if (category === "cargo") { 63 | cargoDependencyUpdated = true; 64 | } 65 | } 66 | } 67 | } 68 | 69 | const newVersionsJSONString = `${JSON.stringify(versions, null, 2)}\n`; 70 | 71 | // Save updated versions.json 72 | writeFileSync(versionsFilePath, newVersionsJSONString); 73 | 74 | // Print updated versions.json to stdout 75 | console.log(`Updated versions.json:\n${newVersionsJSONString}`); 76 | 77 | // Set CARGO_REGISTRY_DEFAULT if cargoDependencyUpdated is true 78 | if (cargoDependencyUpdated) { 79 | exportVariable("CARGO_REGISTRY_DEFAULT", "fluence"); 80 | } 81 | } catch (error) { 82 | setFailed(error.message); 83 | } 84 | -------------------------------------------------------------------------------- /.github/actions/replace-version/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "replace-version", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "build": "ncc build index.js" 8 | }, 9 | "author": "Cloudless Labs", 10 | "license": "AGPL-3.0", 11 | "dependencies": { 12 | "@actions/core": "^1.10.0" 13 | }, 14 | "devDependencies": { 15 | "@vercel/ncc": "^0.36.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/release-please/config-backport.json: -------------------------------------------------------------------------------- 1 | { 2 | "bootstrap-sha": "ea46c1efd19f8ac3330a0dd845df272b3c53c9a6", 3 | "release-type": "node", 4 | "versioning": "always-bump-patch", 5 | "packages": { 6 | "packages/cli/package": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.github/release-please/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bootstrap-sha": "ea46c1efd19f8ac3330a0dd845df272b3c53c9a6", 3 | "release-type": "node", 4 | "bump-minor-pre-major": true, 5 | "bump-patch-for-minor-pre-major": true, 6 | "packages": { 7 | "packages/cli/package": {} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.github/release-please/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages/cli/package": "0.25.1" 3 | } 4 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["github>fluencelabs/renovate", "github>fluencelabs/renovate:npm"], 3 | "enabledManagers": ["npm", "regex"], 4 | "regexManagers": [ 5 | { 6 | "fileMatch": ["^packages/cli/package/src/versions\\.json$"], 7 | "matchStrings": [ 8 | "\"chain-rpc\": \"(?[^:]+):(?.*)\",\n", 9 | "\"chain-deploy-script\": \"(?[^:]+):(?.*)\",\n", 10 | "\"subgraph-deploy-script\": \"(?[^:]+):(?.*)\",\n" 11 | ], 12 | "datasourceTemplate": "docker", 13 | "depNameTemplate": "chain" 14 | }, 15 | { 16 | "fileMatch": ["^packages/cli/package/src/versions\\.json$"], 17 | "matchStrings": [ 18 | "\"(?@fluencelabs/[^\"]+)\": \"(?[^\"\n]+)\"" 19 | ], 20 | "matchStringsStrategy": "any", 21 | "datasourceTemplate": "npm" 22 | } 23 | ], 24 | "packageRules": [ 25 | { 26 | "matchPackagePatterns": [ 27 | "@fluencelabs/installation-spell", 28 | "@fluencelabs/spell" 29 | ], 30 | "groupName": "spell" 31 | }, 32 | { 33 | "matchPackagePatterns": ["chain", "@fluencelabs/deal-ts-clients"], 34 | "groupName": "deal" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: "docs" 2 | 3 | on: 4 | pull_request: 5 | paths-ignore: 6 | - "!**.md" 7 | 8 | concurrency: 9 | group: "${{ github.workflow }}-${{ github.ref }}" 10 | cancel-in-progress: true 11 | 12 | env: 13 | CI: true 14 | FORCE_COLOR: true 15 | FLUENCE_USER_DIR: "${{ github.workspace }}/tmp/.fluence" 16 | 17 | jobs: 18 | docs: 19 | permissions: 20 | contents: write 21 | id-token: write 22 | env: 23 | TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} 24 | TURBO_TEAM: ${{ vars.TURBO_TEAM }} 25 | name: Generate docs 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v4 30 | with: 31 | token: ${{ secrets.FLUENCEBOT_RELEASE_PLEASE_PAT }} 32 | 33 | - name: Setup node with self-hosted npm registry 34 | uses: actions/setup-node@v4 35 | with: 36 | node-version: "22.10.0" 37 | registry-url: "https://npm.fluence.dev" 38 | cache: "yarn" 39 | 40 | - run: yarn install 41 | 42 | - name: Setup golang 43 | uses: actions/setup-go@v5 44 | 45 | - name: Install json-schema-docs 46 | run: go install github.com/marcusolsson/json-schema-docs@latest 47 | 48 | - name: Cache turbo build setup 49 | uses: actions/cache@v4 50 | with: 51 | path: .turbo 52 | key: ${{ runner.os }}-turbo-${{ github.sha }} 53 | restore-keys: | 54 | ${{ runner.os }}-turbo- 55 | 56 | - name: Import secrets 57 | uses: hashicorp/vault-action@v3.0.0 58 | id: secrets 59 | with: 60 | url: https://vault.fluence.dev 61 | path: jwt/github 62 | role: ci 63 | method: jwt 64 | jwtGithubAudience: "https://github.com/fluencelabs" 65 | jwtTtl: 300 66 | exportToken: false 67 | secrets: | 68 | kv/docker-registry/basicauth/ci username | DOCKER_USERNAME ; 69 | kv/docker-registry/basicauth/ci password | DOCKER_PASSWORD ; 70 | 71 | - name: Login to private docker registry 72 | uses: docker/login-action@v3 73 | with: 74 | registry: docker.fluence.dev 75 | username: ${{ env.DOCKER_USERNAME }} 76 | password: ${{ env.DOCKER_PASSWORD }} 77 | 78 | - name: Run on each commit 79 | run: yarn on-each-commit 80 | 81 | - name: Format 82 | run: yarn format 83 | 84 | - name: Auto-commit 85 | uses: stefanzweifel/git-auto-commit-action@v5 86 | -------------------------------------------------------------------------------- /.github/workflows/e2e.yml: -------------------------------------------------------------------------------- 1 | name: "e2e" 2 | 3 | on: 4 | pull_request: 5 | paths-ignore: 6 | - "**.md" 7 | - ".github/**" 8 | - "!.github/workflows/e2e.yml" 9 | - "!.github/workflows/snapshot.yml" 10 | types: 11 | - "labeled" 12 | - "synchronize" 13 | - "opened" 14 | - "reopened" 15 | push: 16 | branches: 17 | - "main" 18 | paths-ignore: 19 | - "**.md" 20 | - ".github/**" 21 | - "!.github/workflows/e2e.yml" 22 | - "!.github/workflows/snapshot.yml" 23 | 24 | concurrency: 25 | group: "${{ github.workflow }}-${{ github.ref }}" 26 | cancel-in-progress: true 27 | 28 | jobs: 29 | fluence-cli: 30 | if: > 31 | github.event_name == 'push' || 32 | ( 33 | contains(github.event.pull_request.labels.*.name, 'e2e') && 34 | !github.event.pull_request.head.repo.fork 35 | ) 36 | uses: ./.github/workflows/snapshot.yml 37 | with: 38 | ref: ${{ github.ref }} 39 | 40 | fluence-cli-pack: 41 | name: "fluence-cli" 42 | strategy: 43 | fail-fast: false 44 | matrix: 45 | platform: 46 | - linux-x64 47 | - darwin-arm64 48 | if: > 49 | github.event_name == 'push' || 50 | ( 51 | contains(github.event.pull_request.labels.*.name, 'e2e') && 52 | !github.event.pull_request.head.repo.fork 53 | ) 54 | uses: ./.github/workflows/pack.yml 55 | with: 56 | ref: ${{ github.ref }} 57 | platform: ${{ matrix.platform }} 58 | 59 | # registry: 60 | # needs: 61 | # - fluence-cli 62 | # uses: fluencelabs/registry/.github/workflows/tests.yml@main 63 | -------------------------------------------------------------------------------- /.github/workflows/install-test.yml: -------------------------------------------------------------------------------- 1 | name: "install test" 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - "install.sh" 7 | push: 8 | branches: 9 | - "main" 10 | paths: 11 | - "install.sh" 12 | 13 | concurrency: 14 | group: "${{ github.workflow }}-${{ github.ref }}" 15 | cancel-in-progress: true 16 | 17 | env: 18 | FLUENCE_USER_DIR: "${{ github.workspace }}/tmp/.fluence" 19 | 20 | jobs: 21 | test-install: 22 | runs-on: ${{ matrix.os }} 23 | 24 | strategy: 25 | fail-fast: false 26 | matrix: 27 | include: 28 | - os: macos-latest 29 | - os: ubuntu-latest 30 | 31 | steps: 32 | - name: Checkout fluence-cli 33 | uses: actions/checkout@v4 34 | with: 35 | repository: fluencelabs/cli 36 | 37 | - name: Run install.sh script 38 | run: ./install.sh 39 | 40 | - name: Check fluence 41 | run: ${FLUENCE_USER_DIR}/cli/bin/fluence --version 42 | 43 | - name: Cleanup 44 | if: always() 45 | run: rm -rf tmp ~/.fluence 46 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | concurrency: 11 | group: "${{ github.workflow }}-${{ github.ref }}" 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | pr: 16 | name: Validate PR title 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: amannn/action-semantic-pull-request@v5 20 | env: 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | reviewdog: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | 29 | - name: Lint actions 30 | uses: reviewdog/action-actionlint@v1 31 | env: 32 | SHELLCHECK_OPTS: "-e SC2086" 33 | with: 34 | reporter: github-pr-check 35 | fail_on_error: true 36 | 37 | renovate: 38 | runs-on: ubuntu-latest 39 | steps: 40 | - name: Checkout 41 | uses: actions/checkout@v4 42 | 43 | - name: Renovate Config Validator 44 | uses: tj-actions/renovate-config-validator@v2 45 | with: 46 | config_file: .github/renovate.json 47 | -------------------------------------------------------------------------------- /.github/workflows/promote.yml: -------------------------------------------------------------------------------- 1 | name: Promote fluence-cli 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | channel: 7 | description: "Promote version to channel" 8 | type: choice 9 | options: 10 | - main # latest build from main branch 11 | - stage # version compatible with current stage env 12 | - testnet # version compatible with current testnet env 13 | - stable # latest stable version (same as mainnet) 14 | - mainnet # version compatible with current mainnet env 15 | - v1 # version compatible with mainnet marketplace v1 (old CLI) 16 | - v2 # version compatible with mainnet marketplace v2 (current) 17 | - unstable # version used by all CI jobs; TODO: publish automatically on every release 18 | required: true 19 | ref: 20 | description: "git ref to checkout into" 21 | type: string 22 | required: true 23 | default: "main" 24 | 25 | env: 26 | CI: true 27 | FORCE_COLOR: true 28 | AWS_REGION: "eu-west-1" 29 | AWS_S3_FORCE_PATH_STYLE: true 30 | 31 | jobs: 32 | pack: 33 | strategy: 34 | fail-fast: false 35 | matrix: 36 | platform: 37 | - linux-x64 38 | - darwin-x64 39 | - darwin-arm64 40 | - win32-x64 41 | 42 | uses: ./.github/workflows/pack.yml 43 | with: 44 | ref: ${{ inputs.ref }} 45 | platform: ${{ matrix.platform }} 46 | upload-to-s3: true 47 | channel: ${{ inputs.channel }} 48 | 49 | promote: 50 | name: "Promote fcli" 51 | needs: pack 52 | runs-on: ubuntu-latest 53 | 54 | permissions: 55 | contents: write 56 | id-token: write 57 | 58 | steps: 59 | - name: Checkout fluence-cli 60 | uses: actions/checkout@v4 61 | with: 62 | repository: fluencelabs/cli 63 | ref: ${{ inputs.ref }} 64 | 65 | - name: Import secrets 66 | uses: hashicorp/vault-action@v3.0.0 67 | id: secrets 68 | with: 69 | url: https://vault.fluence.dev 70 | path: jwt/github 71 | role: ci 72 | method: jwt 73 | jwtGithubAudience: "https://github.com/fluencelabs" 74 | jwtTtl: 300 75 | exportToken: false 76 | secrets: | 77 | kv/ci/fcli-binaries id | AWS_ACCESS_KEY_ID ; 78 | kv/ci/fcli-binaries secret | AWS_SECRET_ACCESS_KEY 79 | 80 | - name: Setup node 81 | uses: actions/setup-node@v4 82 | with: 83 | node-version: "22.10.0" 84 | registry-url: "https://npm.fluence.dev" 85 | cache: "yarn" 86 | 87 | - run: yarn install 88 | working-directory: packages/cli/package 89 | 90 | - name: Promote fluence-cli 91 | working-directory: packages/cli/package 92 | run: yarn oclif promote -t linux-x64,darwin-x64,darwin-arm64 --version "$(jq .[] -r ../../../.github/release-please/manifest.json)" --sha "$(git rev-parse --short HEAD)" --channel ${{ inputs.channel }} --no-xz --indexes 93 | 94 | - name: Promote fluence-cli windows 95 | working-directory: packages/cli/package 96 | run: yarn oclif promote -t win32-x64 --version "$(jq .[] -r ../../../.github/release-please/manifest.json)" --sha "$(git rev-parse --short HEAD)" --channel ${{ inputs.channel }} --no-xz --win --indexes 97 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: "test" 2 | 3 | on: 4 | pull_request: 5 | paths-ignore: 6 | - "!**.md" 7 | push: 8 | branches: 9 | - "main" 10 | 11 | concurrency: 12 | group: "${{ github.workflow }}-${{ github.ref }}" 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | fluence-cli: 17 | uses: ./.github/workflows/tests.yml 18 | with: 19 | ref: ${{ github.ref }} 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .yarn/* 2 | !.yarn/patches 3 | !.yarn/plugins 4 | !.yarn/releases 5 | !.yarn/sdks 6 | !.yarn/versions 7 | 8 | # Swap the comments on the following lines if you wish to use zero-installs 9 | # In that case, don't forget to run `yarn config set enableGlobalCache false`! 10 | # Documentation here: https://yarnpkg.com/features/caching#zero-installs 11 | 12 | #!.yarn/cache 13 | .pnp.* 14 | node_modules 15 | .turbo 16 | 17 | dist 18 | 19 | tsconfig.tsbuildinfo 20 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | docs 3 | node_modules 4 | tmp 5 | .fluence 6 | gqlSchema.json 7 | gqlGenerated.ts 8 | CHANGELOG.md 9 | .github/workflows 10 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "editorconfig.editorconfig", 6 | "streetsidesoftware.code-spell-checker", 7 | "redhat.vscode-yaml" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.experimental.useFlatConfig": true, 3 | "eslint.workingDirectories": [ 4 | "cli", 5 | "packages/cli-connector", 6 | "packages/common" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | enableHardenedMode: false 2 | 3 | nodeLinker: node-modules 4 | 5 | yarnPath: .yarn/releases/yarn-4.5.0.cjs 6 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Fluence CLI 2 | Copyright 2024 Fluence DAO 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fluence CLI 2 | 3 | Fluence is a decentralized serverless platform & computing marketplace powered 4 | by blockchain economics. Fluence is a global, permissionless, scalable, and 5 | secure alternative to centralized cloud computing platforms. 6 | 7 | Fluence CLI is designed to be the only tool that you need to manage the life 8 | cycle of applications written on [Fluence](https://fluence.network). It provides 9 | project scaffolding, compilation, service deployment, dependency management and 10 | installation, storage of keys and ids, etc. 11 | 12 | ## CLI installation 13 | 14 | ### Windows 15 | 16 | To download and install `fluence` use Windows `.exe` installer from the [release](https://github.com/fluencelabs/cli/releases) page. 17 | 18 | ### Linux and macOS 19 | 20 | To download and install `fluence` use our `install.sh` script 21 | 22 | ```shell 23 | curl -qsL https://raw.githubusercontent.com/fluencelabs/cli/main/install.sh | bash 24 | ``` 25 | 26 | **Installing manually** 27 | 28 | - download fluence archive for your platform from 29 | [latest release](https://github.com/fluencelabs/cli/releases/latest). 30 | - extract archive contents to default fluence user directory 31 | 32 | ```shell 33 | tar --strip-components=1 -xzf -C "${HOME}/.fluence/cli" 34 | ``` 35 | 36 | - add `${HOME}/.fluence/cli/bin` to `$PATH` 37 | 38 | ### Update 39 | 40 | To select `fluence` version compatible with certain network (`stage`, `testnet`, `mainnet`) run: 41 | 42 | ```shell 43 | fluence update 44 | ``` 45 | 46 | You will receive notifications about updates when new version is promoted. 47 | 48 | For more information run: 49 | 50 | ```shell 51 | fluence update --help 52 | ``` 53 | 54 | ## Uninstall CLI 55 | 56 | **Windows** 57 | 58 | Go to installation directory and run `Uninstall.exe` binary. 59 | 60 | **Linux and macOS** 61 | 62 | To uninstall CLI you need to remove couple of directories 63 | 64 | ```sh 65 | rm -rf ~/.fluence 66 | rm -rf ~/.local/share/fluence 67 | ``` 68 | 69 | You can also remove `${HOME}/.fluence/cli/bin` from `$PATH` e.g. like that: 70 | 71 | ```sh 72 | rm $(which fluence) 73 | ``` 74 | 75 | ## Documentation 76 | 77 | 1. [A complete list of commands together with usage examples](./packages/cli/package/docs/commands/README.md) 78 | 1. [Documentation for all Fluence CLI configs](./packages/cli/package/docs/configs/README.md) 79 | 1. [Environment variables that affect Fluence CLI and are important for Fluence CLI maintainers](./packages/cli/package/example.env) 80 | 81 | ## Support 82 | 83 | Please, file an [issue](https://github.com/fluencelabs/cli/issues) if you find a 84 | bug. You can also contact us at [Discord](https://discord.com/invite/5qSnPZKh7u) 85 | or [Telegram](https://t.me/fluence_project). We will do our best to resolve the 86 | issue ASAP. 87 | 88 | ## Contributing 89 | 90 | Any interested person is welcome to contribute to the project. Please, make sure 91 | you read and follow some basic [rules](./CONTRIBUTING.md). 92 | 93 | ## License 94 | 95 | All software code is copyright (c) Fluence DAO. under the 96 | [GNU Affero General Public License version 3](./LICENSE) license. 97 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit -o nounset -o pipefail 3 | 4 | # Function to check if a command exists 5 | has() { 6 | [[ -z $1 ]] && return 1 7 | command -v $1 >/dev/null 2>&1 8 | } 9 | 10 | echo "Initiating Fluence CLI installation process..." 11 | 12 | # Determine the operating system and machine architecture 13 | OS="$(uname -s | tr '[:upper:]' '[:lower:]')" 14 | ARCH="$(uname -m)" 15 | 16 | # Setting the installation directory for Fluence CLI 17 | FLUENCE_USER_DIR="${FLUENCE_USER_DIR-$HOME/.fluence}" 18 | 19 | # Creating a temporary directory and ensuring its cleanup on script exit 20 | TEMP="$(mktemp -d)" 21 | trap "rm -rf '$TEMP'" EXIT INT TERM 22 | 23 | # Ensuring 'curl' is installed for downloading necessary files 24 | if ! has "curl"; then 25 | echo "Error: Installation requires 'curl'. Please install 'curl' and try again." 26 | exit 1 27 | fi 28 | 29 | # Check that fluence is not installed 30 | if has "fluence"; then 31 | cat </dev/null); then 41 | cat <. 16 | */ 17 | 18 | // @ts-check 19 | 20 | import { dirname, join } from "path"; 21 | import { fileURLToPath } from "url"; 22 | 23 | import repoEslintConfigReact from "@repo/eslint-config/react.js"; 24 | import tseslint from "typescript-eslint"; 25 | 26 | const __filename = fileURLToPath(import.meta.url); 27 | const __dirname = dirname(__filename); 28 | 29 | export default tseslint.config( 30 | ...repoEslintConfigReact, 31 | { 32 | languageOptions: { 33 | parserOptions: { 34 | project: [ 35 | join(__dirname, "tsconfig.json"), 36 | join(__dirname, "tsconfig.node.json"), 37 | ], 38 | }, 39 | }, 40 | }, 41 | { 42 | ignores: ["dist/**", "src/vite-env.d.ts", "eslint.config.js"], 43 | }, 44 | ); 45 | -------------------------------------------------------------------------------- /packages/cli-connector/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Fluence CLI Connector 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/cli-connector/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/cli-connector", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "license": "AGPL-3.0", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "tsc && vite build", 10 | "watch": "vite build -w --minify false -m development", 11 | "preview": "vite preview", 12 | "lint-fix": "eslint . --fix", 13 | "on-each-commit": "yarn lint-fix", 14 | "ncu": "ncu -u" 15 | }, 16 | "dependencies": { 17 | "@rainbow-me/rainbowkit": "^2.1.6", 18 | "@repo/common": "*", 19 | "@tanstack/react-query": "5.56.2", 20 | "buffer": "^6.0.3", 21 | "react": "^18.3.1", 22 | "react-dom": "^18.3.1", 23 | "valibot": "^0.42.0", 24 | "viem": "^2.21.7", 25 | "wagmi": "^2.12.11" 26 | }, 27 | "devDependencies": { 28 | "@repo/eslint-config": "*", 29 | "@total-typescript/ts-reset": "0.6.1", 30 | "@tsconfig/strictest": "2.0.5", 31 | "@tsconfig/vite-react": "3.0.2", 32 | "@types/react": "^18.3.6", 33 | "@types/react-dom": "^18.3.0", 34 | "@vitejs/plugin-react-swc": "3.7.0", 35 | "eslint": "9.10.0", 36 | "npm-check-updates": "^17.1.1", 37 | "typescript": "5.6.2", 38 | "typescript-eslint": "8.5.0", 39 | "vite": "5.4.6" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/cli-connector/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluencelabs/cli/afc6de9b8abe94763ef937cfe8870a7dc3f5f31b/packages/cli-connector/public/favicon.ico -------------------------------------------------------------------------------- /packages/cli-connector/src/index.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | * { 8 | border: none; 9 | background-color: initial; 10 | color: inherit; 11 | font-family: inherit; 12 | } 13 | 14 | html { 15 | display: flex; 16 | font-size: 18px; 17 | min-height: 100%; 18 | font-family: sans-serif; 19 | padding-top: 10vh; 20 | } 21 | 22 | body { 23 | display: flex; 24 | width: 100%; 25 | min-width: 320px; 26 | flex-direction: column; 27 | flex-grow: 1; 28 | } 29 | 30 | h1 { 31 | font-size: 20px; 32 | white-space: pre; 33 | max-width: 100%; 34 | overflow: auto; 35 | } 36 | 37 | #root { 38 | display: flex; 39 | width: 100%; 40 | flex-direction: column; 41 | flex-grow: 1; 42 | } 43 | 44 | #root > div[data-rk] { 45 | display: flex; 46 | flex-direction: column; 47 | align-items: center; 48 | width: 100%; 49 | flex-grow: 1; 50 | } 51 | 52 | details { 53 | max-height: 30vh; 54 | max-width: 700px; 55 | overflow: auto; 56 | } 57 | 58 | summary { 59 | text-align: center; 60 | cursor: pointer; 61 | } 62 | 63 | .button { 64 | appearance: none; 65 | display: flex; 66 | justify-content: center; 67 | padding: 12px; 68 | cursor: pointer; 69 | margin-top: 30px; 70 | margin-bottom: 10px; 71 | border-radius: 12px; 72 | background-color: #000; 73 | color: #fff; 74 | font-size: inherit; 75 | } 76 | 77 | .button_disabled { 78 | cursor: not-allowed; 79 | opacity: 0.5; 80 | } 81 | 82 | .error { 83 | max-width: 100%; 84 | overflow: auto; 85 | color: #d70000; 86 | white-space: pre; 87 | margin-top: 5px; 88 | margin-bottom: 5px; 89 | } 90 | -------------------------------------------------------------------------------- /packages/cli-connector/src/main.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import "@rainbow-me/rainbowkit/styles.css"; 19 | 20 | import { Buffer } from "buffer"; 21 | 22 | import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit"; 23 | import { CLIToConnectorFullMsg } from "@repo/common"; 24 | import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; 25 | import React from "react"; 26 | import { useState, useEffect } from "react"; 27 | import ReactDOM from "react-dom/client"; 28 | import { WagmiProvider, deepEqual } from "wagmi"; 29 | 30 | import { App } from "./App.jsx"; 31 | import "./index.css"; 32 | 33 | globalThis.Buffer = Buffer; 34 | 35 | const queryClient = new QueryClient(); 36 | const root = document.getElementById("root"); 37 | 38 | if (root === null) { 39 | throw new Error("Root element not found"); 40 | } 41 | 42 | export function AppWrapper() { 43 | const [chain, setChain] = useState< 44 | CLIToConnectorFullMsg["chain"] | undefined 45 | >(undefined); 46 | 47 | useEffect(() => { 48 | if (chain !== undefined) { 49 | return; 50 | } 51 | 52 | const eventSource = new EventSource("/events"); 53 | 54 | eventSource.onmessage = ({ data }) => { 55 | // We are sure CLI returns what we expect so there is no need to validate 56 | // eslint-disable-next-line @typescript-eslint/consistent-type-assertions 57 | const { chain: chainFromCLI } = JSON.parse( 58 | // eslint-disable-next-line @typescript-eslint/consistent-type-assertions 59 | data as string, 60 | ) as CLIToConnectorFullMsg; 61 | 62 | if (!deepEqual(chain, chainFromCLI)) { 63 | setChain(chainFromCLI); 64 | } 65 | }; 66 | }, [chain, setChain]); 67 | 68 | if (chain === undefined) { 69 | return; 70 | } 71 | 72 | const config = getDefaultConfig({ 73 | appName: "Fluence CLI Connector", 74 | projectId: "YOUR_PROJECT_ID", 75 | chains: [ 76 | { 77 | ...chain, 78 | nativeCurrency: { 79 | decimals: 18, 80 | name: "Fluence", 81 | symbol: chain.name === "Fluence Mainnet" ? "FLT" : "tFLT", 82 | }, 83 | testnet: chain.name !== "Fluence Mainnet", 84 | }, 85 | ], 86 | }); 87 | 88 | return ( 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | ); 97 | } 98 | 99 | ReactDOM.createRoot(root).render( 100 | 101 | 102 | , 103 | ); 104 | -------------------------------------------------------------------------------- /packages/cli-connector/src/reset.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import "@total-typescript/ts-reset"; 19 | -------------------------------------------------------------------------------- /packages/cli-connector/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/cli-connector/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/strictest/tsconfig", "@tsconfig/vite-react/tsconfig"], 3 | "include": ["src"], 4 | "references": [{ "path": "./tsconfig.node.json" }] 5 | } 6 | -------------------------------------------------------------------------------- /packages/cli-connector/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/strictest/tsconfig", 3 | "compilerOptions": { 4 | "composite": true, 5 | "skipLibCheck": true, 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "allowSyntheticDefaultImports": true 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli-connector/vite.config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import react from "@vitejs/plugin-react-swc"; 19 | import { defineConfig } from "vite"; 20 | 21 | export default defineConfig({ 22 | plugins: [react()], 23 | // Disable chunk size warning cause this frontend is only used on local server 24 | build: { chunkSizeWarningLimit: Infinity }, 25 | }); 26 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/cli", 3 | "private": true, 4 | "dependencies": { 5 | "@repo/cli-connector": "*", 6 | "@repo/common": "*" 7 | }, 8 | "scripts": { 9 | "install-yarn-dependencies": "yarn ./package install", 10 | "gen-gql-schema": "yarn ./package gen-gql-schema", 11 | "gql-codegen": "yarn ./package gql-codegen", 12 | "before-build": "yarn ./package before-build", 13 | "build": "yarn ./package build", 14 | "pack-ci": "yarn ./package pack-ci", 15 | "pack-linux-x64": "yarn ./package pack-linux-x64", 16 | "pack-darwin-x64": "yarn ./package pack-darwin-x64", 17 | "pack-darwin-arm64": "yarn ./package pack-darwin-arm64", 18 | "pack-win32-x64": "yarn ./package pack-win32-x64", 19 | "on-each-commit": "yarn ./package on-each-commit", 20 | "vitest-provider": "yarn ./package vitest-provider" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/package/.gitignore: -------------------------------------------------------------------------------- 1 | # oclif default 2 | **/.DS_Store 3 | *-debug.log 4 | *-error.log 5 | /.idea 6 | /.nyc_output 7 | /dist 8 | /lib 9 | oclif.lock 10 | oclif.manifest.json 11 | .eslintcache 12 | tmp 13 | 14 | # for ease of development 15 | /schemas 16 | /.f 17 | .env 18 | docker-compose.yaml 19 | 20 | # recommended by Fluence 21 | .idea 22 | .DS_Store 23 | .fluence 24 | **/target/ 25 | .repl_history 26 | 27 | # ignore compiled files 28 | src/lib/gql/gqlGenerated.ts 29 | src/lib/gql/gqlSchema.json 30 | src/versions 31 | src/common.ts 32 | 33 | .yarn/* 34 | !.yarn/patches 35 | !.yarn/plugins 36 | !.yarn/releases 37 | !.yarn/sdks 38 | !.yarn/versions 39 | 40 | # Swap the comments on the following lines if you wish to use zero-installs 41 | # In that case, don't forget to run `yarn config set enableGlobalCache false`! 42 | # Documentation here: https://yarnpkg.com/features/caching#zero-installs 43 | 44 | #!.yarn/cache 45 | .pnp.* 46 | node_modules 47 | -------------------------------------------------------------------------------- /packages/cli/package/.yarn/patches/oclif-npm-4.15.9-f51cd140c1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/commands/pack/win.js b/lib/commands/pack/win.js 2 | index 488e61a50e3183a2183b69f8a8571cb9523bdae4..f71e9d9d2c87a5b8aef4f672ac9cb01398f3e4dc 100644 3 | --- a/lib/commands/pack/win.js 4 | +++ b/lib/commands/pack/win.js 5 | @@ -37,12 +37,13 @@ const scripts = { 6 | /* eslint-disable no-useless-escape */ 7 | cmd: (config, additionalCLI) => `@echo off 8 | setlocal enableextensions 9 | +set NODE_NO_WARNINGS=1 10 | 11 | set ${additionalCLI ? `${additionalCLI.toUpperCase()}_BINPATH` : config.scopedEnvVarKey('BINPATH')}=%~dp0\\${additionalCLI ?? config.bin}.cmd 12 | if exist "%LOCALAPPDATA%\\${config.dirname}\\client\\bin\\${additionalCLI ?? config.bin}.cmd" ( 13 | "%LOCALAPPDATA%\\${config.dirname}\\client\\bin\\${additionalCLI ?? config.bin}.cmd" %* 14 | ) else ( 15 | - "%~dp0\\..\\client\\bin\\node.exe" "%~dp0\\..\\client\\${additionalCLI ? `${additionalCLI}\\bin\\run` : 'bin\\run'}" %* 16 | + "%~dp0\\..\\client\\bin\\fluence.cmd" %* 17 | ) 18 | `, 19 | nsis: ({ arch, config, customization, defenderOptional, hideDefenderOption, }) => `!include MUI2.nsh 20 | @@ -268,7 +269,7 @@ the CLI should already exist in a directory named after the CLI that is the root 21 | const nsisCustomization = config.nsisCustomization ? (0, node_fs_1.readFileSync)(config.nsisCustomization, 'utf8') : ''; 22 | const arches = buildConfig.targets.filter((t) => t.platform === 'win32').map((t) => t.arch); 23 | await Tarballs.build(buildConfig, { 24 | - pack: false, 25 | + pack: true, 26 | parallel: true, 27 | platform: 'win32', 28 | pruneLockfiles: flags['prune-lockfiles'], 29 | diff --git a/lib/tarballs/bin.js b/lib/tarballs/bin.js 30 | index 9272ce0ff10b1f09c3c8dbbb7e2ccdf72dc8268e..3ba9b823baf13e7c65ccf76b5f531339bfee7316 100644 31 | --- a/lib/tarballs/bin.js 32 | +++ b/lib/tarballs/bin.js 33 | @@ -57,6 +57,8 @@ if exist "%~dp0..\\bin\\node.exe" ( 34 | const writeUnix = async () => { 35 | const bin = path.join(baseWorkspace, 'bin', config.bin); 36 | await fs.promises.writeFile(bin, `#!/usr/bin/env bash 37 | +export NODE_NO_WARNINGS=1 38 | + 39 | set -e 40 | echoerr() { echo "$@" 1>&2; } 41 | 42 | -------------------------------------------------------------------------------- /packages/cli/package/.yarn/patches/oclif-patch-c5b232dd7e.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/aws.js b/lib/aws.js 2 | index de23a617995470968ef472e242a9de263bc6f363..e27793ede9c02e841e7bca2ca2a53544b9f11f25 100644 3 | --- a/lib/aws.js 4 | +++ b/lib/aws.js 5 | @@ -2,9 +2,10 @@ 6 | Object.defineProperty(exports, "__esModule", { value: true }); 7 | const client_cloudfront_1 = require("@aws-sdk/client-cloudfront"); 8 | const client_s3_1 = require("@aws-sdk/client-s3"); 9 | +const lib_storage_1 = require("@aws-sdk/lib-storage"); 10 | +const promises_1 = require("node:fs/promises"); 11 | const errors_1 = require("@oclif/core/errors"); 12 | const ux_1 = require("@oclif/core/ux"); 13 | -const fs_extra_1 = require("fs-extra"); 14 | const log_1 = require("./log"); 15 | const util_1 = require("./util"); 16 | const debug = log_1.debug.new('aws'); 17 | @@ -129,11 +130,13 @@ exports.default = { 18 | ux_1.ux.stdout(); 19 | if (dryRun) 20 | return; 21 | - options.Body = (0, fs_extra_1.createReadStream)(local); 22 | - aws.s3 23 | - ?.send(new client_s3_1.PutObjectCommand(options)) 24 | - .then((data) => resolve(data)) 25 | - .catch((error) => reject(error)); 26 | + promises_1.readFile(local).then((Body) => { 27 | + options.Body = Body; 28 | + new lib_storage_1.Upload({ client: aws.s3, params: options }) 29 | + .done() 30 | + .then((data) => resolve(data)) 31 | + .catch((error) => reject(error)); 32 | + }) 33 | }), 34 | }; 35 | }, 36 | -------------------------------------------------------------------------------- /packages/cli/package/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | enableHardenedMode: false 2 | 3 | nodeLinker: node-modules 4 | 5 | npmRegistryServer: "https://npm.fluence.dev" 6 | 7 | yarnPath: .yarn/releases/yarn-4.5.0.cjs 8 | -------------------------------------------------------------------------------- /packages/cli/package/bin/dev.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S node --no-warnings --no-deprecation --import tsx 2 | 3 | /** 4 | * Fluence CLI 5 | * Copyright (C) 2024 Fluence DAO 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Affero General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Affero General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | import oclif from "@oclif/core"; 21 | 22 | import { 23 | setUpProcessWarningListener, 24 | createErrorPromise, 25 | } from "../src/errorInterceptor.js"; 26 | 27 | setUpProcessWarningListener(); 28 | 29 | // In dev mode -> use tsx and dev plugins 30 | process.env.NODE_ENV = "development"; 31 | // In dev mode, always show stack traces 32 | oclif.settings.debug = true; 33 | 34 | // Start the CLI 35 | oclif 36 | .run(process.argv.slice(2), import.meta.url) 37 | .then(oclif.flush) 38 | .catch( 39 | /** @param {unknown} error */ 40 | (error) => { 41 | return createErrorPromise(error); 42 | }, 43 | ); 44 | -------------------------------------------------------------------------------- /packages/cli/package/bin/run.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | node "%~dp0\run.js" %* 4 | -------------------------------------------------------------------------------- /packages/cli/package/bin/run.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S node --no-warnings --no-deprecation 2 | 3 | /** 4 | * Fluence CLI 5 | * Copyright (C) 2024 Fluence DAO 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Affero General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Affero General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | import oclif from "@oclif/core"; 21 | 22 | import { 23 | createErrorPromise, 24 | setUpProcessWarningListener, 25 | } from "../dist/errorInterceptor.js"; 26 | 27 | setUpProcessWarningListener(); 28 | 29 | oclif 30 | .run(process.argv.slice(2), import.meta.url) 31 | .then(oclif.flush) 32 | .catch( 33 | /** @param {unknown} error */ (error) => { 34 | return createErrorPromise(error); 35 | }, 36 | ); 37 | -------------------------------------------------------------------------------- /packages/cli/package/docs/configs/README.md: -------------------------------------------------------------------------------- 1 | # Fluence CLI Configs 2 | 3 | ## [provider.yaml](./provider.md) 4 | 5 | Defines provider configuration 6 | 7 | ## [provider-secrets.yaml](./provider-secrets.md) 8 | 9 | Defines secrets config used for provider set up 10 | 11 | ## [config.yaml](./config.md) 12 | 13 | Defines global config for Fluence CLI 14 | 15 | ## [env.yaml](./env.md) 16 | 17 | Defines project user's preferences 18 | 19 | ## [provider-artifacts.yaml](./provider-artifacts.md) 20 | 21 | Defines artifacts created by the provider -------------------------------------------------------------------------------- /packages/cli/package/docs/configs/config.md: -------------------------------------------------------------------------------- 1 | # config.yaml 2 | 3 | Defines global config for Fluence CLI 4 | 5 | ## Properties 6 | 7 | | Property | Type | Required | Description | 8 | |------------------------|---------|----------|--------------------------------------------------------------------------------------------------------| 9 | | `countlyConsent` | boolean | **Yes** | Weather you consent to send usage data to Countly | 10 | | `version` | integer | **Yes** | Config version | 11 | | `defaultSecretKeyName` | string | No | DEPRECATED: Secret key with this name will be used by default by js-client inside CLI to run Aqua code | 12 | | `docsInConfigs` | boolean | No | DEPRECATED: Whether to include docs in generated configs | 13 | 14 | -------------------------------------------------------------------------------- /packages/cli/package/docs/configs/provider-secrets.md: -------------------------------------------------------------------------------- 1 | # provider-secrets.yaml 2 | 3 | Defines secrets config used for provider set up 4 | 5 | ## Properties 6 | 7 | | Property | Type | Required | Description | 8 | |-----------|------------------|----------|-------------------------------| 9 | | `noxes` | [object](#noxes) | **Yes** | Secret keys for noxes by name | 10 | | `version` | integer | **Yes** | Config version | 11 | 12 | ## noxes 13 | 14 | Secret keys for noxes by name 15 | 16 | ### Properties 17 | 18 | | Property | Type | Required | Description | 19 | |-----------|--------------------|----------|----------------------------------------------------------------------------------| 20 | | `noxName` | [object](#noxname) | No | Secret keys for noxes. You can put it near provider config and populate it in CI | 21 | 22 | ### noxName 23 | 24 | Secret keys for noxes. You can put it near provider config and populate it in CI 25 | 26 | #### Properties 27 | 28 | | Property | Type | Required | Description | 29 | |-----------------|--------|----------|-----------------------------------------------------------| 30 | | `networkKey` | string | **Yes** | Network key for the nox | 31 | | `signingWallet` | string | **Yes** | Signing wallet for built-in decider system service in nox | 32 | 33 | -------------------------------------------------------------------------------- /packages/cli/package/example.env: -------------------------------------------------------------------------------- 1 | # Display debug logs for cli and dependencies 2 | # DEBUG=fcli:debug 3 | 4 | # Remove colors from CLI output 5 | # FORCE_COLOR=0 6 | 7 | # Fluence network to use for tests. Can be 'testnet', 'stage', 'mainnet' or 'local' 8 | # 'local' multiaddresses are currently hardcoded at `src/lib/multiaddres.ts` 9 | # FLUENCE_ENV="local" 10 | 11 | # To set path for the user's .fluence dir. Default: ~/.fluence (for Windows: %LOCALAPPDATA%\fluence) 12 | # FLUENCE_USER_DIR="/absolute/path/to/users/.fluence" 13 | 14 | 15 | # CLI Dependency override examples 16 | # FCLI_V_CHAIN="docker.fluence.dev/aurora:0.2.11" 17 | 18 | # environment variables to be used by Fluence CLI maintainers to develop Fluence CLI: 19 | 20 | # To turn on Countly debugger 21 | # DEBUG_COUNTLY="true" 22 | 23 | # example of npm env variables 24 | # You also need to do `npm login --registry=https://npm.fluence.dev` after that 25 | # NPM_CONFIG_REGISTRY="https://npm.fluence.dev" 26 | -------------------------------------------------------------------------------- /packages/cli/package/nsis/Plugins/amd64-unicode/EnVar.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluencelabs/cli/afc6de9b8abe94763ef937cfe8870a7dc3f5f31b/packages/cli/package/nsis/Plugins/amd64-unicode/EnVar.dll -------------------------------------------------------------------------------- /packages/cli/package/nsis/Plugins/x86-ansi/EnVar.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluencelabs/cli/afc6de9b8abe94763ef937cfe8870a7dc3f5f31b/packages/cli/package/nsis/Plugins/x86-ansi/EnVar.dll -------------------------------------------------------------------------------- /packages/cli/package/nsis/Plugins/x86-unicode/EnVar.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluencelabs/cli/afc6de9b8abe94763ef937cfe8870a7dc3f5f31b/packages/cli/package/nsis/Plugins/x86-unicode/EnVar.dll -------------------------------------------------------------------------------- /packages/cli/package/nsis/custom-installer.nsi: -------------------------------------------------------------------------------- 1 | !include "winmessages.nsh" 2 | 3 | ShowInstDetails show 4 | ShowUninstDetails show 5 | 6 | !addplugindir "../../nsis/Plugins/x86-unicode" 7 | 8 | !define env_hkcu 'HKCU "Environment"' 9 | 10 | Section "@fluencelabs/cli CLI ${VERSION}" 11 | SetOutPath $INSTDIR 12 | File /r bin 13 | File /r client 14 | ExpandEnvStrings $0 "%COMSPEC%" 15 | 16 | WriteRegStr HKCU "Software\fluence" "" $INSTDIR 17 | WriteUninstaller "$INSTDIR\Uninstall.exe" 18 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\fluence" \ 19 | "DisplayName" "@fluencelabs/cli" 20 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\fluence" \ 21 | "DisplayVersion" "${VERSION}" 22 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\fluence" \ 23 | "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" 24 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\fluence" \ 25 | "Publisher" "Cloudless Labs" 26 | 27 | WriteRegExpandStr ${env_hkcu} "FLUENCE_OCLIF_CLIENT_HOME" "$INSTDIR\client" 28 | SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 29 | SectionEnd 30 | 31 | Section "Set PATH to @fluencelabs/cli" 32 | Push $0 33 | EnVar::AddValue "PATH" "" # Need to call 'EnVar::AddValue' with empty string before the actual write to PATH otherwise junk will be written for unknown reason 34 | EnVar::AddValue "PATH" "$INSTDIR\bin" 35 | Pop $0 36 | DetailPrint "EnVar::AddValue returned=|$0|" 37 | Pop $0 38 | SectionEnd 39 | 40 | Section /o "Add %LOCALAPPDATA%\fluence to Windows Defender exclusions (highly recommended for performance!)" 41 | ExecShell "" '"$0"' "/C powershell -ExecutionPolicy Bypass -Command $\"& {Add-MpPreference -ExclusionPath $\"$LOCALAPPDATA\fluence$\"}$\" -FFFeatureOff" SW_HIDE 42 | SectionEnd 43 | 44 | Section "Uninstall" 45 | Delete "$INSTDIR\Uninstall.exe" 46 | RMDir /r "$INSTDIR" 47 | RMDir /r "$LOCALAPPDATA\fluence" 48 | DeleteRegKey /ifempty HKCU "Software\fluence" 49 | DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\fluence" 50 | 51 | DeleteRegValue ${env_hkcu} "FLUENCE_OCLIF_CLIENT_HOME" 52 | SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 53 | SectionEnd 54 | 55 | # TODO: Make a PR to oclif's repo with the proposal to upgrade their codebase 56 | 57 | /* 58 | This script patches the default installation script in Oclif's sources. 59 | The open comment symbol is used to exclude all following code from getting to the installer. 60 | Unfortunately oclif's code isn't perfect and contains bugs. 61 | -------------------------------------------------------------------------------- /packages/cli/package/nsis/include/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluencelabs/cli/afc6de9b8abe94763ef937cfe8870a7dc3f5f31b/packages/cli/package/nsis/include/.gitkeep -------------------------------------------------------------------------------- /packages/cli/package/resources/license-header.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | -------------------------------------------------------------------------------- /packages/cli/package/src/baseCommand.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { Command, type Interfaces } from "@oclif/core"; 19 | 20 | import { NO_INPUT_FLAG } from "./lib/const.js"; 21 | import { exitCli } from "./lib/lifeCycle.js"; 22 | 23 | type Flags = Interfaces.InferredFlags< 24 | (typeof BaseCommand)["baseFlags"] & T["flags"] 25 | >; 26 | type Args = Interfaces.InferredArgs; 27 | 28 | const baseFlags = { 29 | ...NO_INPUT_FLAG, 30 | }; 31 | 32 | export abstract class BaseCommand extends Command { 33 | protected flags!: Flags; 34 | protected args!: Args; 35 | static override baseFlags = baseFlags; 36 | 37 | protected override async finally( 38 | maybeError: Error | undefined, 39 | ): Promise { 40 | // called after run and catch regardless of whether or not the command errored 41 | if (maybeError === undefined) { 42 | await super.finally(maybeError); 43 | await exitCli(); 44 | } 45 | 46 | return super.finally(maybeError); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/cli/package/src/beforeBuild.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | // @ts-check 19 | import { cp, mkdir, rm } from "node:fs/promises"; 20 | import { join, resolve, dirname } from "node:path"; 21 | import { fileURLToPath } from "node:url"; 22 | 23 | const __filename = fileURLToPath(import.meta.url); 24 | const __dirname = dirname(__filename); 25 | const root = resolve(__dirname, ".."); 26 | 27 | const VERSIONS_DIR_PATH = join(root, "src", "versions"); 28 | 29 | await rm(VERSIONS_DIR_PATH, { recursive: true, force: true }); 30 | await mkdir(VERSIONS_DIR_PATH, { recursive: true }); 31 | await cp("package.json", join(VERSIONS_DIR_PATH, "cli.package.json")); 32 | 33 | await cp( 34 | resolve(root, "..", "..", "common", "src", "index.ts"), 35 | resolve(root, "src", "common.ts"), 36 | ); 37 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/chain/info.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { jsonStringify, LOCAL_NET_DEFAULT_ACCOUNTS } from "../../common.js"; 20 | import { 21 | getBlockScoutUrl, 22 | getChainId, 23 | getRpcUrl, 24 | getSubgraphUrl, 25 | } from "../../lib/chain/chainConfig.js"; 26 | import { commandObj } from "../../lib/commandObj.js"; 27 | import { CHAIN_FLAGS } from "../../lib/const.js"; 28 | import { resolveDeployment } from "../../lib/dealClient.js"; 29 | import { ensureChainEnv } from "../../lib/ensureChainNetwork.js"; 30 | import { initCli } from "../../lib/lifeCycle.js"; 31 | 32 | export default class Info extends BaseCommand { 33 | static override description = 34 | "Show contract addresses for the fluence environment and accounts for the local environment"; 35 | static override flags = { 36 | ...CHAIN_FLAGS, 37 | }; 38 | 39 | async run(): Promise { 40 | await initCli(this, await this.parse(Info)); 41 | const chainEnv = await ensureChainEnv(); 42 | 43 | commandObj.log( 44 | jsonStringify({ 45 | ...(chainEnv === "local" 46 | ? { defaultAccountsForLocalEnv: LOCAL_NET_DEFAULT_ACCOUNTS } 47 | : {}), 48 | contracts: await resolveDeployment(), 49 | subgraphUrl: await getSubgraphUrl(), 50 | chainId: await getChainId(), 51 | chainRPC: await getRpcUrl(), 52 | ...(await getBlockScoutUrl()), 53 | }), 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/default/env.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { color } from "@oclif/color"; 19 | 20 | import { BaseCommand } from "../../baseCommand.js"; 21 | import { commandObj } from "../../lib/commandObj.js"; 22 | import { initNewEnvConfig } from "../../lib/configs/project/env/env.js"; 23 | import { ENV_ARG } from "../../lib/const.js"; 24 | import { initCli } from "../../lib/lifeCycle.js"; 25 | import { ensureValidFluenceEnv } from "../../lib/resolveFluenceEnv.js"; 26 | 27 | export default class Env extends BaseCommand { 28 | static override description = "Switch default Fluence Environment"; 29 | static override examples = ["<%= config.bin %> <%= command.id %>"]; 30 | static override args = { 31 | ...ENV_ARG, 32 | }; 33 | async run(): Promise { 34 | const { args } = await initCli(this, await this.parse(Env)); 35 | const envConfig = await initNewEnvConfig(); 36 | const fluenceEnv = await ensureValidFluenceEnv(args.ENV); 37 | envConfig.fluenceEnv = fluenceEnv; 38 | await envConfig.$commit(); 39 | 40 | commandObj.log( 41 | `Successfully set default fluence environment to ${color.yellow( 42 | fluenceEnv, 43 | )}`, 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/local/down.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { dirname } from "path"; 19 | 20 | import { Flags } from "@oclif/core"; 21 | 22 | import { BaseCommand } from "../../baseCommand.js"; 23 | import { ensureDockerComposeConfig } from "../../lib/configs/project/dockerCompose.js"; 24 | import { 25 | DOCKER_COMPOSE_FULL_FILE_NAME, 26 | DOCKER_COMPOSE_FLAGS, 27 | } from "../../lib/const.js"; 28 | import { dockerCompose } from "../../lib/dockerCompose.js"; 29 | import { initCli } from "../../lib/lifeCycle.js"; 30 | 31 | export default class Down extends BaseCommand { 32 | static override description = `Stop and remove currently running ${DOCKER_COMPOSE_FULL_FILE_NAME} using docker compose`; 33 | static override examples = ["<%= config.bin %> <%= command.id %>"]; 34 | static override flags = { 35 | volumes: Flags.boolean({ 36 | char: "v", 37 | description: 38 | 'Remove named volumes declared in the "volumes" section of the Compose file and anonymous volumes attached to containers', 39 | default: false, 40 | }), 41 | ...DOCKER_COMPOSE_FLAGS, 42 | }; 43 | async run(): Promise { 44 | const { flags } = await initCli(this, await this.parse(Down)); 45 | const dockerComposeConfigPath = await ensureDockerComposeConfig(); 46 | 47 | await dockerCompose({ 48 | args: [ 49 | "down", 50 | ...(flags.flags === undefined ? [] : flags.flags.split(" ")), 51 | ], 52 | flags: { v: flags.volumes }, 53 | printOutput: true, 54 | options: { cwd: dirname(dockerComposeConfigPath) }, 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/local/init.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { rm } from "fs/promises"; 19 | 20 | import { color } from "@oclif/color"; 21 | 22 | import { BaseCommand } from "../../baseCommand.js"; 23 | import { commandObj } from "../../lib/commandObj.js"; 24 | import { 25 | ensureDockerComposeConfig, 26 | checkDockerComposeConfigExists, 27 | } from "../../lib/configs/project/dockerCompose.js"; 28 | import { initNewProviderConfig } from "../../lib/configs/project/provider/provider.js"; 29 | import { 30 | DOCKER_COMPOSE_FULL_FILE_NAME, 31 | PROVIDER_CONFIG_FULL_FILE_NAME, 32 | CHAIN_FLAGS, 33 | } from "../../lib/const.js"; 34 | import { initCli } from "../../lib/lifeCycle.js"; 35 | import { confirm } from "../../lib/prompt.js"; 36 | 37 | export default class Init extends BaseCommand { 38 | static override description = `Init ${DOCKER_COMPOSE_FULL_FILE_NAME} according to ${PROVIDER_CONFIG_FULL_FILE_NAME}`; 39 | static override examples = ["<%= config.bin %> <%= command.id %>"]; 40 | static override flags = { 41 | ...CHAIN_FLAGS, 42 | }; 43 | async run(): Promise { 44 | await initCli(this, await this.parse(Init)); 45 | await initNewProviderConfig(); 46 | const existingDockerComposePath = await checkDockerComposeConfigExists(); 47 | 48 | if (existingDockerComposePath !== null) { 49 | const isOverwriting = await confirm({ 50 | message: `Do you want to replace existing ${color.yellow( 51 | existingDockerComposePath, 52 | )}`, 53 | default: false, 54 | }); 55 | 56 | if (!isOverwriting) { 57 | commandObj.error( 58 | `The config already exists at ${existingDockerComposePath}. Aborting.`, 59 | ); 60 | } 61 | 62 | await rm(existingDockerComposePath); 63 | } 64 | 65 | const dockerComposePath = await ensureDockerComposeConfig(); 66 | commandObj.logToStderr(`Created new config at ${dockerComposePath}`); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/local/logs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { dirname } from "path"; 19 | 20 | import { BaseCommand } from "../../baseCommand.js"; 21 | import { commandObj } from "../../lib/commandObj.js"; 22 | import { checkDockerComposeConfigExists } from "../../lib/configs/project/dockerCompose.js"; 23 | import { 24 | DOCKER_COMPOSE_FULL_FILE_NAME, 25 | DOCKER_COMPOSE_FLAGS, 26 | } from "../../lib/const.js"; 27 | import { dockerCompose } from "../../lib/dockerCompose.js"; 28 | import { initCli } from "../../lib/lifeCycle.js"; 29 | 30 | export default class Logs extends BaseCommand { 31 | static override description = `Display ${DOCKER_COMPOSE_FULL_FILE_NAME} logs`; 32 | static override examples = ["<%= config.bin %> <%= command.id %>"]; 33 | static override flags = { 34 | ...DOCKER_COMPOSE_FLAGS, 35 | }; 36 | async run(): Promise { 37 | const { flags } = await initCli(this, await this.parse(Logs)); 38 | const dockerComposeConfigPath = await checkDockerComposeConfigExists(); 39 | 40 | if (dockerComposeConfigPath === null) { 41 | commandObj.error( 42 | `Cannot find ${DOCKER_COMPOSE_FULL_FILE_NAME}. Aborting.`, 43 | ); 44 | } 45 | 46 | const logs = await dockerCompose({ 47 | args: [ 48 | "logs", 49 | ...(flags.flags === undefined ? [] : flags.flags.split(" ")), 50 | ], 51 | options: { cwd: dirname(dockerComposeConfigPath) }, 52 | }); 53 | 54 | commandObj.log(logs); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/local/ps.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { dirname } from "path"; 19 | 20 | import { BaseCommand } from "../../baseCommand.js"; 21 | import { commandObj } from "../../lib/commandObj.js"; 22 | import { checkDockerComposeConfigExists } from "../../lib/configs/project/dockerCompose.js"; 23 | import { 24 | DOCKER_COMPOSE_FULL_FILE_NAME, 25 | DOCKER_COMPOSE_FLAGS, 26 | } from "../../lib/const.js"; 27 | import { dockerCompose } from "../../lib/dockerCompose.js"; 28 | import { initCli } from "../../lib/lifeCycle.js"; 29 | 30 | export default class PS extends BaseCommand { 31 | static override description = `List containers using docker compose`; 32 | static override examples = ["<%= config.bin %> <%= command.id %>"]; 33 | static override flags = { 34 | ...DOCKER_COMPOSE_FLAGS, 35 | }; 36 | async run(): Promise { 37 | const { flags } = await initCli(this, await this.parse(PS)); 38 | const dockerComposeConfigPath = await checkDockerComposeConfigExists(); 39 | 40 | if (dockerComposeConfigPath === null) { 41 | commandObj.error( 42 | `Cannot find ${DOCKER_COMPOSE_FULL_FILE_NAME}. Aborting.`, 43 | ); 44 | } 45 | 46 | const psResult = await dockerCompose({ 47 | args: [ 48 | "ps", 49 | ...(flags.flags === undefined ? [] : flags.flags.split(" ")), 50 | ], 51 | options: { cwd: dirname(dockerComposeConfigPath) }, 52 | }); 53 | 54 | commandObj.log(psResult); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/cc-activate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { depositCollateral } from "../../lib/chain/depositCollateral.js"; 20 | import { CC_FLAGS, CHAIN_FLAGS, FLT_SYMBOL } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class AddCollateral extends BaseCommand { 25 | static override hiddenAliases = ["provider:ca"]; 26 | static override description = `Add ${FLT_SYMBOL} collateral to capacity commitment to activate it${aliasesText.apply(this)}`; 27 | static override flags = { 28 | ...CHAIN_FLAGS, 29 | ...CC_FLAGS, 30 | }; 31 | 32 | async run(): Promise { 33 | const { flags } = await initCli(this, await this.parse(AddCollateral)); 34 | await depositCollateral(flags); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/cc-create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { createCommitments } from "../../lib/chain/commitment.js"; 20 | import { CHAIN_FLAGS, PEER_AND_OFFER_NAMES_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class CreateCommitment extends BaseCommand< 25 | typeof CreateCommitment 26 | > { 27 | static override hiddenAliases = ["provider:cc"]; 28 | static override description = `Create Capacity commitment${aliasesText.apply(this)}`; 29 | static override flags = { 30 | ...CHAIN_FLAGS, 31 | ...PEER_AND_OFFER_NAMES_FLAGS, 32 | }; 33 | 34 | async run(): Promise { 35 | const { flags } = await initCli(this, await this.parse(CreateCommitment)); 36 | await createCommitments(flags); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/cc-finish.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { collateralWithdraw } from "../../lib/chain/commitment.js"; 20 | import { CHAIN_FLAGS, FLT_SYMBOL, CC_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class CCFinish extends BaseCommand { 25 | static override hiddenAliases = [ 26 | "provider:ccf", 27 | "provider:cc-collateral-withdraw", 28 | ]; 29 | static override description = `Move resources from deals, withdraw ${FLT_SYMBOL} collateral from capacity commitments, remove compute units from capacity commitments and finish capacity commitments${aliasesText.apply(this)}`; 30 | static override flags = { 31 | ...CC_FLAGS, 32 | ...CHAIN_FLAGS, 33 | }; 34 | 35 | async run(): Promise { 36 | const { flags } = await initCli(this, await this.parse(CCFinish)); 37 | await collateralWithdraw(flags); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/cc-info.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { jsonStringify } from "../../common.js"; 20 | import { 21 | getDetailedCommitmentsInfoGroupedByStatus, 22 | stringifyDetailedCommitmentsInfo, 23 | } from "../../lib/chain/commitment.js"; 24 | import { commandObj } from "../../lib/commandObj.js"; 25 | import { CHAIN_FLAGS, CC_FLAGS, JSON_FLAG } from "../../lib/const.js"; 26 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 27 | import { initCli } from "../../lib/lifeCycle.js"; 28 | 29 | export default class CCInfo extends BaseCommand { 30 | static override hiddenAliases = ["provider:ci"]; 31 | static override description = `Get info about capacity commitments${aliasesText.apply(this)}`; 32 | static override flags = { 33 | ...CHAIN_FLAGS, 34 | ...CC_FLAGS, 35 | ...JSON_FLAG, 36 | }; 37 | 38 | async run(): Promise { 39 | const { flags } = await initCli(this, await this.parse(CCInfo)); 40 | 41 | const ccInfo = await getDetailedCommitmentsInfoGroupedByStatus(flags); 42 | 43 | commandObj.log( 44 | flags.json 45 | ? jsonStringify( 46 | ccInfo.flatMap(({ CCs }) => { 47 | return CCs; 48 | }), 49 | ) 50 | : await stringifyDetailedCommitmentsInfo(ccInfo), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/cc-remove.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { removeCommitments } from "../../lib/chain/commitment.js"; 20 | import { CC_FLAGS, CHAIN_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class RemoveCommitment extends BaseCommand< 25 | typeof RemoveCommitment 26 | > { 27 | static override hiddenAliases = ["provider:cr"]; 28 | static override description = `Remove Capacity commitment. You can remove it only BEFORE you activated it by depositing collateral${aliasesText.apply(this)}`; 29 | static override flags = { 30 | ...CHAIN_FLAGS, 31 | ...CC_FLAGS, 32 | }; 33 | 34 | async run(): Promise { 35 | const { flags } = await initCli(this, await this.parse(RemoveCommitment)); 36 | await removeCommitments(flags); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/cc-rewards-withdraw.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { collateralRewardWithdraw } from "../../lib/chain/commitment.js"; 20 | import { CHAIN_FLAGS, FLT_SYMBOL, CC_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class CCRewardsWithdraw extends BaseCommand< 25 | typeof CCRewardsWithdraw 26 | > { 27 | static override hiddenAliases = ["provider:crw"]; 28 | static override description = `Withdraw ${FLT_SYMBOL} rewards from capacity commitments${aliasesText.apply(this)}`; 29 | static override flags = { 30 | ...CC_FLAGS, 31 | ...CHAIN_FLAGS, 32 | }; 33 | 34 | async run(): Promise { 35 | const { flags } = await initCli(this, await this.parse(CCRewardsWithdraw)); 36 | await collateralRewardWithdraw(flags); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/deal-list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { commandObj } from "../../lib/commandObj.js"; 20 | // import { getProviderDeals } from "../../lib/chain/deals.js"; 21 | // import { commandObj } from "../../lib/commandObj.js"; 22 | import { CHAIN_FLAGS } from "../../lib/const.js"; 23 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 24 | import { initCli } from "../../lib/lifeCycle.js"; 25 | 26 | export default class DealsList extends BaseCommand { 27 | static override hiddenAliases = ["provider:dl"]; 28 | static override description = `List all deals${aliasesText.apply(this)}`; 29 | static override flags = { 30 | ...CHAIN_FLAGS, 31 | }; 32 | 33 | async run(): Promise { 34 | await initCli(this, await this.parse(DealsList)); 35 | 36 | commandObj.error( 37 | "This command is temporary not working. Please use explorer to see deals", 38 | ); 39 | // commandObj.log((await getProviderDeals()).join("\n")); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/deal-rewards-info.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { color } from "@oclif/color"; 19 | import { Args } from "@oclif/core"; 20 | 21 | import { BaseCommand } from "../../baseCommand.js"; 22 | import { ptFormatWithSymbol } from "../../lib/chain/currencies.js"; 23 | import { commandObj } from "../../lib/commandObj.js"; 24 | import { CHAIN_FLAGS } from "../../lib/const.js"; 25 | import { getReadonlyContracts } from "../../lib/dealClient.js"; 26 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 27 | import { initCli } from "../../lib/lifeCycle.js"; 28 | import { input } from "../../lib/prompt.js"; 29 | 30 | export default class DealRewardsInfo extends BaseCommand< 31 | typeof DealRewardsInfo 32 | > { 33 | static override hiddenAliases = ["provider:dri"]; 34 | static override description = `Deal rewards info${aliasesText.apply(this)}`; 35 | static override flags = { 36 | ...CHAIN_FLAGS, 37 | }; 38 | 39 | static override args = { 40 | "DEAL-ADDRESS": Args.string({ 41 | description: "Deal address", 42 | }), 43 | "ON-CHAIN-WORKER-ID": Args.string({ 44 | description: "On-chain worker id", 45 | }), 46 | }; 47 | 48 | async run(): Promise { 49 | const { args } = await initCli(this, await this.parse(DealRewardsInfo)); 50 | 51 | const dealAddress = 52 | args["DEAL-ADDRESS"] ?? (await input({ message: "Enter deal address" })); 53 | 54 | const onChainWorkerId = 55 | args["ON-CHAIN-WORKER-ID"] ?? 56 | (await input({ message: "Enter on-chain worker id" })); 57 | 58 | const { readonlyContracts } = await getReadonlyContracts(); 59 | const deal = readonlyContracts.getDealV2(dealAddress); 60 | const rewardAmount = await deal.getRewardAmount(onChainWorkerId); 61 | 62 | commandObj.log( 63 | `Provider reward: ${color.yellow( 64 | await ptFormatWithSymbol(rewardAmount.providerReward), 65 | )}\n\nStaker reward: ${color.yellow( 66 | await ptFormatWithSymbol(rewardAmount.stakerReward), 67 | )}`, 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/deploy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { CHAIN_FLAGS, PEER_AND_OFFER_NAMES_FLAGS } from "../../lib/const.js"; 20 | import { initCli } from "../../lib/lifeCycle.js"; 21 | import { deployManifests } from "../../lib/manifestsDeploy.js"; 22 | 23 | export default class Deploy extends BaseCommand { 24 | static override description = "Deploy manifests"; 25 | static override examples = ["<%= config.bin %> <%= command.id %>"]; 26 | static override flags = { 27 | ...CHAIN_FLAGS, 28 | ...PEER_AND_OFFER_NAMES_FLAGS, 29 | }; 30 | async run(): Promise { 31 | const { flags } = await initCli(this, await this.parse(Deploy)); 32 | await deployManifests({ flags }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/init.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { writeFile } from "node:fs/promises"; 19 | 20 | import { color } from "@oclif/color"; 21 | 22 | import { BaseCommand } from "../../baseCommand.js"; 23 | import { commandObj } from "../../lib/commandObj.js"; 24 | import { 25 | initNewProviderConfig, 26 | initProviderConfig, 27 | } from "../../lib/configs/project/provider/provider.js"; 28 | import { 29 | CHAIN_FLAGS, 30 | PEERS_FLAG, 31 | PROVIDER_CONFIG_FULL_FILE_NAME, 32 | RECOMMENDED_GITIGNORE_CONTENT, 33 | } from "../../lib/const.js"; 34 | import { initCli } from "../../lib/lifeCycle.js"; 35 | import { getGitignorePath } from "../../lib/paths.js"; 36 | 37 | export default class Init extends BaseCommand { 38 | static override description = `Init provider config. Creates a ${PROVIDER_CONFIG_FULL_FILE_NAME} file`; 39 | static override flags = { 40 | ...PEERS_FLAG, 41 | ...CHAIN_FLAGS, 42 | }; 43 | 44 | async run(): Promise { 45 | const { flags } = await initCli(this, await this.parse(Init)); 46 | 47 | let providerConfig = await initProviderConfig(); 48 | 49 | if (providerConfig !== null) { 50 | return commandObj.error( 51 | `Provider config already exists at ${color.yellow( 52 | providerConfig.$getPath(), 53 | )}. If you want to init a new provider config, please do it in another directory`, 54 | ); 55 | } 56 | 57 | providerConfig = await initNewProviderConfig(flags); 58 | 59 | await writeFile(getGitignorePath(), RECOMMENDED_GITIGNORE_CONTENT, "utf8"); 60 | 61 | commandObj.logToStderr( 62 | `Provider config is at ${color.yellow(providerConfig.$getPath())}`, 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/offer-create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { createOffers } from "../../lib/chain/offer/offer.js"; 20 | import { OFFER_FLAG, CHAIN_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class CreateOffer extends BaseCommand { 25 | static override hiddenAliases = ["provider:oc"]; 26 | static override description = `Create offers. You have to be registered as a provider to do that${aliasesText.apply(this)}`; 27 | static override flags = { 28 | ...CHAIN_FLAGS, 29 | ...OFFER_FLAG, 30 | }; 31 | 32 | async run(): Promise { 33 | const { flags } = await initCli(this, await this.parse(CreateOffer)); 34 | await createOffers(flags); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/offer-info.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { 20 | resolveCreatedOffers, 21 | getOffersInfo, 22 | offersInfoToString, 23 | } from "../../lib/chain/offer/offer.js"; 24 | import { commandObj } from "../../lib/commandObj.js"; 25 | import { CHAIN_FLAGS, OFFER_FLAGS } from "../../lib/const.js"; 26 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 27 | import { initCli } from "../../lib/lifeCycle.js"; 28 | 29 | export default class OfferInfo extends BaseCommand { 30 | static override hiddenAliases = ["provider:oi"]; 31 | static override description = `Get info about offers${aliasesText.apply(this)}`; 32 | static override flags = { 33 | ...OFFER_FLAGS, 34 | ...CHAIN_FLAGS, 35 | }; 36 | 37 | async run(): Promise { 38 | const { flags } = await initCli(this, await this.parse(OfferInfo)); 39 | const offers = await resolveCreatedOffers(flags); 40 | const offerInfoResult = await getOffersInfo(offers); 41 | commandObj.log(await offersInfoToString(offerInfoResult)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/offer-remove.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { removeOffers } from "../../lib/chain/offer/updateOffers.js"; 20 | import { CHAIN_FLAGS, OFFER_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class OfferRemove extends BaseCommand { 25 | static override hiddenAliases = ["provider:or"]; 26 | static override description = `Remove offers${aliasesText.apply(this)}`; 27 | static override flags = { 28 | ...OFFER_FLAGS, 29 | ...CHAIN_FLAGS, 30 | }; 31 | 32 | async run(): Promise { 33 | const { flags } = await initCli(this, await this.parse(OfferRemove)); 34 | await removeOffers(flags); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/offer-update.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { updateOffers } from "../../lib/chain/offer/updateOffers.js"; 20 | import { CHAIN_FLAGS, OFFER_FLAG } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class OfferUpdate extends BaseCommand { 25 | static override hiddenAliases = ["provider:ou"]; 26 | static override description = `Update offers${aliasesText.apply(this)}`; 27 | static override flags = { 28 | ...OFFER_FLAG, 29 | ...CHAIN_FLAGS, 30 | }; 31 | 32 | async run(): Promise { 33 | const { flags } = await initCli(this, await this.parse(OfferUpdate)); 34 | await updateOffers(flags); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/register.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { registerProvider } from "../../lib/chain/providerInfo.js"; 20 | import { CHAIN_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class Register extends BaseCommand { 25 | static override hiddenAliases = ["provider:r"]; 26 | static override description = `Register as a provider${aliasesText.apply(this)}`; 27 | static override flags = { 28 | ...CHAIN_FLAGS, 29 | }; 30 | 31 | async run(): Promise { 32 | await initCli(this, await this.parse(Register)); 33 | await registerProvider(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/tokens-distribute.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { Flags } from "@oclif/core"; 19 | 20 | import { BaseCommand } from "../../baseCommand.js"; 21 | import { distributeToPeer } from "../../lib/chain/distributeToNox.js"; 22 | import { 23 | CHAIN_FLAGS, 24 | FLT_SYMBOL, 25 | PEER_AND_OFFER_NAMES_FLAGS, 26 | } from "../../lib/const.js"; 27 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 28 | import { initCli } from "../../lib/lifeCycle.js"; 29 | 30 | export default class TokensDistribute extends BaseCommand< 31 | typeof TokensDistribute 32 | > { 33 | static override hiddenAliases = ["provider:td"]; 34 | static override description = `Distribute ${FLT_SYMBOL} tokens to peers${aliasesText.apply(this)}`; 35 | static override flags = { 36 | ...CHAIN_FLAGS, 37 | ...PEER_AND_OFFER_NAMES_FLAGS, 38 | amount: Flags.string({ 39 | description: `Amount of ${FLT_SYMBOL} tokens to distribute to peers`, 40 | }), 41 | }; 42 | 43 | async run(): Promise { 44 | const { flags } = await initCli(this, await this.parse(TokensDistribute)); 45 | await distributeToPeer(flags); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/tokens-withdraw.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { Flags } from "@oclif/core"; 19 | 20 | import { BaseCommand } from "../../baseCommand.js"; 21 | import { withdrawFromPeer } from "../../lib/chain/distributeToNox.js"; 22 | import { 23 | CHAIN_FLAGS, 24 | FLT_SYMBOL, 25 | MAX_TOKEN_AMOUNT_KEYWORD, 26 | PEER_AND_OFFER_NAMES_FLAGS, 27 | } from "../../lib/const.js"; 28 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 29 | import { initCli } from "../../lib/lifeCycle.js"; 30 | 31 | const AMOUNT_FLAG_NAME = "amount"; 32 | 33 | export default class TokensWithdraw extends BaseCommand { 34 | static override hiddenAliases = ["provider:tw"]; 35 | static override description = `Withdraw ${FLT_SYMBOL} tokens from peers${aliasesText.apply(this)}`; 36 | static override flags = { 37 | ...CHAIN_FLAGS, 38 | ...PEER_AND_OFFER_NAMES_FLAGS, 39 | [AMOUNT_FLAG_NAME]: Flags.string({ 40 | description: `Amount of ${FLT_SYMBOL} tokens to withdraw from peers. Use --${AMOUNT_FLAG_NAME} ${MAX_TOKEN_AMOUNT_KEYWORD} to withdraw maximum possible amount`, 41 | }), 42 | }; 43 | 44 | async run(): Promise { 45 | const { flags } = await initCli(this, await this.parse(TokensWithdraw)); 46 | await withdrawFromPeer(flags); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/cli/package/src/commands/provider/update.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { BaseCommand } from "../../baseCommand.js"; 19 | import { updateProvider } from "../../lib/chain/providerInfo.js"; 20 | import { CHAIN_FLAGS } from "../../lib/const.js"; 21 | import { aliasesText } from "../../lib/helpers/aliasesText.js"; 22 | import { initCli } from "../../lib/lifeCycle.js"; 23 | 24 | export default class Update extends BaseCommand { 25 | static override hiddenAliases = ["provider:u"]; 26 | static override description = `Update provider info${aliasesText.apply(this)}`; 27 | static override flags = { 28 | ...CHAIN_FLAGS, 29 | }; 30 | 31 | async run(): Promise { 32 | await initCli(this, await this.parse(Update)); 33 | await updateProvider(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/cli/package/src/environment.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { 19 | DEBUG_COUNTLY, 20 | FLUENCE_ENV, 21 | FLUENCE_USER_DIR, 22 | CI, 23 | } from "../src/lib/setupEnvironment.js"; 24 | 25 | import { ChainENV } from "./common.js"; 26 | 27 | declare global { 28 | namespace NodeJS { 29 | interface ProcessEnv { 30 | [FLUENCE_ENV]: ChainENV; 31 | [DEBUG_COUNTLY]: "true" | "false"; 32 | [FLUENCE_USER_DIR]?: string; 33 | [CI]: "true" | "false"; 34 | PATH: string; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/cli/package/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | export { run } from "@oclif/core"; 19 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/ajvInstance.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { color } from "@oclif/color"; 19 | import Ajv from "ajv"; 20 | import addFormats from "ajv-formats"; 21 | 22 | import { jsonStringify } from "../common.js"; 23 | 24 | import { HEX_REGEX } from "./helpers/validations.js"; 25 | 26 | export function getAjv() { 27 | const ajv = new Ajv.default({ 28 | allowUnionTypes: true, 29 | code: { esm: true }, 30 | }); 31 | 32 | addFormats.default(ajv); 33 | ajv.addFormat("hex", HEX_REGEX); 34 | return ajv; 35 | } 36 | 37 | export const ajv = getAjv(); 38 | 39 | type AjvErrors = 40 | | Ajv.ErrorObject>[] 41 | | null 42 | | undefined; 43 | 44 | export async function validationErrorToString(errors: AjvErrors) { 45 | if (errors === null || errors === undefined) { 46 | return ""; 47 | } 48 | 49 | const { stringify } = await import("yaml"); 50 | 51 | return ( 52 | "Errors:\n\n" + 53 | errors 54 | .map(({ instancePath, params, message }, i) => { 55 | const paramsMessage = 56 | Object.keys(params).length === 0 ? "" : `\n${stringify(params)}`; 57 | 58 | const prevError = errors[i - 1]; 59 | 60 | const isDuplicateError = 61 | prevError?.instancePath === instancePath && 62 | jsonStringify(prevError.params) === jsonStringify(params) && 63 | prevError.message === message; 64 | 65 | if (isDuplicateError) { 66 | return ""; 67 | } 68 | 69 | return `${instancePath === "" ? "" : `${color.yellow(instancePath)} `}${message ?? ""}${paramsMessage}`; 70 | }) 71 | .filter((s) => { 72 | return s !== ""; 73 | }) 74 | .join("\n") 75 | ); 76 | } 77 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/chain/currencies.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { FLT_SYMBOL, PT_SYMBOL } from "../const.js"; 19 | import { dbg } from "../dbg.js"; 20 | import { getReadonlyContracts } from "../dealClient.js"; 21 | import { numToStr } from "../helpers/typesafeStringify.js"; 22 | 23 | export async function fltParse(value: string): Promise { 24 | const { parseEther } = await import("ethers"); 25 | return parseEther(value); 26 | } 27 | 28 | async function fltFormat(value: bigint): Promise { 29 | const { formatEther } = await import("ethers"); 30 | return formatEther(value); 31 | } 32 | 33 | export async function fltFormatWithSymbol(value: bigint): Promise { 34 | return `${await fltFormat(value)} ${FLT_SYMBOL}`; 35 | } 36 | 37 | export async function ptParse(value: string): Promise { 38 | const { parseUnits } = await import("ethers"); 39 | return parseUnits(value, await getPtDecimals()); 40 | } 41 | 42 | export async function ptFormat(value: bigint): Promise { 43 | const { formatUnits } = await import("ethers"); 44 | return formatUnits(value, await getPtDecimals()); 45 | } 46 | 47 | export async function ptFormatWithSymbol(value: bigint): Promise { 48 | return `${await ptFormat(value)} ${PT_SYMBOL}`; 49 | } 50 | 51 | let ptDecimalsPromise: Promise | undefined; 52 | 53 | async function getPtDecimals() { 54 | if (ptDecimalsPromise === undefined) { 55 | ptDecimalsPromise = (async () => { 56 | const { id } = await import("ethers"); 57 | 58 | const { readonlyContracts, jsonRpcProvider } = 59 | await getReadonlyContracts(); 60 | 61 | const decimalsRaw = await jsonRpcProvider.call({ 62 | to: readonlyContracts.deployment.usdc, 63 | data: id("decimals()").substring(0, 10), 64 | }); 65 | 66 | const decimals = parseInt(decimalsRaw); 67 | dbg(`Got ${PT_SYMBOL} number of decimals: ${numToStr(decimals)}`); 68 | return decimals; 69 | })(); 70 | } 71 | 72 | return ptDecimalsPromise; 73 | } 74 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/chainFlags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { commandObj } from "./commandObj.js"; 19 | import { ENV_FLAG_NAME, PRIV_KEY_FLAG_NAME } from "./const.js"; 20 | 21 | type ChainFlags = { 22 | [ENV_FLAG_NAME]?: string | undefined; 23 | [PRIV_KEY_FLAG_NAME]?: string | undefined; 24 | }; 25 | 26 | export let chainFlags: ChainFlags = {}; 27 | 28 | export function setChainFlags(flags: ChainFlags) { 29 | let env = flags[ENV_FLAG_NAME]; 30 | 31 | if (env === "kras") { 32 | commandObj.warn(`'kras' is deprecated, use 'mainnet' instead`); 33 | env = "mainnet"; 34 | } else if (env === "dar") { 35 | commandObj.warn(`'dar' is deprecated, use 'testnet' instead`); 36 | env = "testnet"; 37 | } 38 | 39 | chainFlags = { 40 | ...flags, 41 | ...(env === undefined ? {} : { [ENV_FLAG_NAME]: env }), 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/commandObj.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import type { Command } from "@oclif/core"; 19 | import { CLIError } from "@oclif/core/errors"; 20 | 21 | export type CommandObj = InstanceType; 22 | export let commandObj: CommandObj = 23 | // eslint-disable-next-line @typescript-eslint/consistent-type-assertions 24 | { 25 | log(msg: string) { 26 | // eslint-disable-next-line no-console 27 | console.log(msg); 28 | }, 29 | logToStderr(msg: string) { 30 | // eslint-disable-next-line no-console 31 | console.error(msg); 32 | }, 33 | error(msg: string): never { 34 | throw new CLIError(msg); 35 | }, 36 | warn(msg: string) { 37 | // eslint-disable-next-line no-console 38 | console.warn(msg); 39 | }, 40 | config: {}, 41 | } as CommandObj; 42 | export let isInteractive: boolean; 43 | 44 | export const setCommandObjAndIsInteractive = ( 45 | newCommandObj: CommandObj, 46 | newIsInteractive: boolean, 47 | ): void => { 48 | commandObj = newCommandObj; 49 | isInteractive = newIsInteractive; 50 | }; 51 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/dockerCompose.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { writeFile } from "fs/promises"; 19 | 20 | import { pathExists } from "../../helpers/utils.js"; 21 | import { ensureDockerComposeConfigPath } from "../../paths.js"; 22 | 23 | import { chainContainers } from "./chainContainers.js"; 24 | 25 | export async function ensureDockerComposeConfig() { 26 | const configPath = await ensureDockerComposeConfigPath(); 27 | 28 | if (!(await pathExists(configPath))) { 29 | const { stringify } = await import("yaml"); 30 | await writeFile(configPath, stringify(chainContainers)); 31 | } 32 | 33 | return configPath; 34 | } 35 | 36 | export async function checkDockerComposeConfigExists() { 37 | const configPath = await ensureDockerComposeConfigPath(); 38 | return (await pathExists(configPath)) ? configPath : null; 39 | } 40 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/env/env.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { type FluenceEnv } from "../../../const.js"; 19 | import { getEnvConfigPath } from "../../../paths.js"; 20 | import { getConfigInitFunction } from "../../initConfigNew.js"; 21 | import { type InitConfigOptions } from "../../initConfigNewTypes.js"; 22 | 23 | import configOptions0, { type Config as Config0 } from "./env0.js"; 24 | import configOptions1, { type Config as Config1 } from "./env1.js"; 25 | import configOptions2, { type Config as Config2 } from "./env2.js"; 26 | 27 | export const options: InitConfigOptions = { 28 | description: "Defines project user's preferences", 29 | options: [configOptions0, configOptions1, configOptions2], 30 | getConfigPath: getEnvConfigPath, 31 | }; 32 | 33 | export function initNewEnvConfig(fluenceEnv?: FluenceEnv) { 34 | return getConfigInitFunction(options, () => { 35 | return fluenceEnv === undefined ? {} : { fluenceEnv }; 36 | })(); 37 | } 38 | 39 | export const initEnvConfig = getConfigInitFunction(options); 40 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/env/env0.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { FLUENCE_ENVS_OLD, type FluenceEnvOld } from "../../../const.js"; 19 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 20 | 21 | export type Config = { 22 | fluenceEnv?: FluenceEnvOld; 23 | }; 24 | 25 | export default { 26 | schema: { 27 | type: "object", 28 | properties: { 29 | fluenceEnv: { 30 | title: "Fluence environment", 31 | description: "Fluence environment to connect to", 32 | type: "string", 33 | enum: [...FLUENCE_ENVS_OLD], 34 | nullable: true, 35 | }, 36 | }, 37 | additionalProperties: false, 38 | }, 39 | } as const satisfies ConfigOptions; 40 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/env/env1.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import type { Deployment } from "@fluencelabs/deal-ts-clients"; 19 | 20 | import { CHAIN_ENV } from "../../../../common.js"; 21 | import { type FluenceEnv, fluenceOldEnvToNewEnv } from "../../../const.js"; 22 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 23 | 24 | import type { Config as PrevConfig } from "./env0.js"; 25 | 26 | export type Config = { 27 | fluenceEnv?: FluenceEnv; 28 | relays?: Array; 29 | subgraphUrl?: string; 30 | rpcUrl?: string; 31 | blockScoutUrl?: string; 32 | chainId?: number; 33 | deployment?: Partial; 34 | ipfsGateway?: string; 35 | }; 36 | 37 | export default { 38 | schema: { 39 | type: "object", 40 | properties: { 41 | fluenceEnv: { 42 | title: "Fluence environment", 43 | description: `Fluence environment to connect to`, 44 | type: "string", 45 | enum: [...CHAIN_ENV], 46 | nullable: true, 47 | }, 48 | relays: { 49 | type: "array", 50 | description: `List of custom relay multiaddresses to use when connecting to Fluence network`, 51 | items: { type: "string" }, 52 | minItems: 1, 53 | nullable: true, 54 | }, 55 | subgraphUrl: { 56 | type: "string", 57 | description: `Subgraph URL to use`, 58 | format: "uri", 59 | nullable: true, 60 | }, 61 | rpcUrl: { 62 | type: "string", 63 | description: `RPC URL to use`, 64 | format: "uri", 65 | nullable: true, 66 | }, 67 | blockScoutUrl: { 68 | type: "string", 69 | description: `BlockScout URL to use`, 70 | format: "uri", 71 | nullable: true, 72 | }, 73 | chainId: { 74 | type: "number", 75 | description: `Chain ID to use`, 76 | nullable: true, 77 | }, 78 | deployment: { 79 | type: "object", 80 | description: `Deployed contract address overrides`, 81 | nullable: true, 82 | required: [], 83 | additionalProperties: false, 84 | properties: { 85 | usdc: { type: "string", nullable: true }, 86 | multicall3: { type: "string", nullable: true }, 87 | diamond: { type: "string", nullable: true }, 88 | balanceKeeper: { type: "string", nullable: true }, 89 | }, 90 | }, 91 | ipfsGateway: { 92 | type: "string", 93 | description: `IPFS gateway URL to use`, 94 | format: "uri", 95 | nullable: true, 96 | }, 97 | }, 98 | additionalProperties: false, 99 | }, 100 | migrate({ fluenceEnv }) { 101 | return fluenceEnv === undefined 102 | ? {} 103 | : { fluenceEnv: fluenceOldEnvToNewEnv(fluenceEnv) }; 104 | }, 105 | } as const satisfies ConfigOptions; 106 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/providerArtifacts/providerArtifacts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { 19 | ensureProviderArtifactsConfigPath, 20 | getFluenceDir, 21 | } from "../../../paths.js"; 22 | import { getConfigInitFunction } from "../../initConfigNew.js"; 23 | import { type InitConfigOptions } from "../../initConfigNewTypes.js"; 24 | 25 | import configOptions0, { 26 | type Config as Config0, 27 | } from "./providerArtifacts0.js"; 28 | import configOptions1, { 29 | type Config as Config1, 30 | } from "./providerArtifacts1.js"; 31 | import configOptions2, { 32 | type Config as Config2, 33 | } from "./providerArtifacts2.js"; 34 | import configOptions3, { 35 | type Config as Config3, 36 | } from "./providerArtifacts3.js"; 37 | 38 | export const options: InitConfigOptions = { 39 | description: "Defines artifacts created by the provider", 40 | options: [configOptions0, configOptions1, configOptions2, configOptions3], 41 | getConfigPath: ensureProviderArtifactsConfigPath, 42 | getSchemaDirPath: getFluenceDir, 43 | }; 44 | 45 | export const initNewProviderArtifactsConfig = getConfigInitFunction( 46 | options, 47 | () => { 48 | return { offers: {} }; 49 | }, 50 | ); 51 | 52 | export const initProviderArtifactsConfig = getConfigInitFunction(options); 53 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/providerArtifacts/providerArtifacts0.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import type { JSONSchemaType } from "ajv"; 19 | 20 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 21 | 22 | export type OfferConfig = { id: string }; 23 | 24 | export const offerConfig = { 25 | type: "object", 26 | additionalProperties: false, 27 | description: "Created offer info", 28 | properties: { id: { type: "string", description: "Offer id" } }, 29 | required: ["id"], 30 | } as const satisfies JSONSchemaType; 31 | 32 | type Offers = Record; 33 | export type Config = { offers: Offers }; 34 | 35 | export default { 36 | schema: { 37 | type: "object", 38 | additionalProperties: false, 39 | properties: { 40 | offers: { 41 | type: "object", 42 | description: "Created offers", 43 | additionalProperties: offerConfig, 44 | properties: { 45 | noxName: offerConfig, 46 | }, 47 | required: [], 48 | }, 49 | }, 50 | required: ["offers"], 51 | }, 52 | } as const satisfies ConfigOptions; 53 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/providerArtifacts/providerArtifacts1.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import type { JSONSchemaType } from "ajv"; 19 | 20 | import type { FluenceEnvOld } from "../../../const.js"; 21 | import { fluenceEnvOldPrompt } from "../../../resolveFluenceEnv.js"; 22 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 23 | 24 | import { 25 | type Config as PrevConfig, 26 | type OfferConfig, 27 | offerConfig, 28 | } from "./providerArtifacts0.js"; 29 | 30 | type OffersConfig = Record; 31 | 32 | const offersConfig = { 33 | type: "object", 34 | description: "Created offers", 35 | additionalProperties: offerConfig, 36 | properties: { noxName: offerConfig }, 37 | required: [], 38 | nullable: true, 39 | } as const satisfies JSONSchemaType; 40 | 41 | type Offers = Partial>; 42 | export type Config = { offers: Offers }; 43 | 44 | export default { 45 | schema: { 46 | type: "object", 47 | additionalProperties: false, 48 | properties: { 49 | offers: { 50 | type: "object", 51 | description: "Created offers", 52 | additionalProperties: false, 53 | properties: { 54 | dar: offersConfig, 55 | custom: offersConfig, 56 | kras: offersConfig, 57 | local: offersConfig, 58 | stage: offersConfig, 59 | }, 60 | required: [], 61 | }, 62 | }, 63 | required: ["offers"], 64 | }, 65 | async migrate(config) { 66 | const offers: Offers = {}; 67 | 68 | for (const [offerName, offer] of Object.entries(config.offers)) { 69 | const env = await fluenceEnvOldPrompt( 70 | `Select the environment that you previously used for creating offer ${offerName} with offerId: ${offer.id}`, 71 | ); 72 | 73 | const dealsForEnv = offers[env] ?? {}; 74 | dealsForEnv[offerName] = offer; 75 | offers[env] = dealsForEnv; 76 | } 77 | 78 | return { offers }; 79 | }, 80 | } as const satisfies ConfigOptions; 81 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/providerArtifacts/providerArtifacts2.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import type { JSONSchemaType } from "ajv"; 19 | 20 | import { 21 | isFluenceEnvOld, 22 | PROVIDER_ARTIFACTS_CONFIG_FULL_FILE_NAME, 23 | type FluenceEnvOld, 24 | } from "../../../const.js"; 25 | import { input } from "../../../prompt.js"; 26 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 27 | 28 | import type { Config as PrevConfig } from "./providerArtifacts1.js"; 29 | 30 | type OfferConfig = { id: string; providerAddress: string }; 31 | 32 | const offerConfig = { 33 | type: "object", 34 | additionalProperties: false, 35 | properties: { 36 | id: { type: "string", description: "Offer id" }, 37 | providerAddress: { 38 | type: "string", 39 | description: "Provider address", 40 | }, 41 | }, 42 | required: ["id", "providerAddress"], 43 | } as const satisfies JSONSchemaType; 44 | 45 | export type OffersConfig = Record; 46 | 47 | export const offersConfig = { 48 | type: "object", 49 | description: "Created offers", 50 | additionalProperties: offerConfig, 51 | properties: { offerName: offerConfig }, 52 | required: [], 53 | nullable: true, 54 | } as const satisfies JSONSchemaType; 55 | 56 | type Offers = Partial>; 57 | export type Config = { offers: Offers }; 58 | 59 | export default { 60 | schema: { 61 | type: "object", 62 | additionalProperties: false, 63 | properties: { 64 | offers: { 65 | type: "object", 66 | description: "Created offers", 67 | additionalProperties: false, 68 | properties: { 69 | dar: offersConfig, 70 | custom: offersConfig, 71 | kras: offersConfig, 72 | local: offersConfig, 73 | stage: offersConfig, 74 | }, 75 | required: [], 76 | }, 77 | }, 78 | required: ["offers"], 79 | }, 80 | async migrate(config) { 81 | const newConfig: Config = { offers: {} }; 82 | 83 | for (const [env, configPerEnv] of Object.entries(config.offers)) { 84 | if (!isFluenceEnvOld(env)) { 85 | throw new Error( 86 | `Unreachable. Migration error. Unknown env ${env} in ${PROVIDER_ARTIFACTS_CONFIG_FULL_FILE_NAME}`, 87 | ); 88 | } 89 | 90 | const newConfigPerEnv: OffersConfig = {}; 91 | 92 | for (const [offerName, offer] of Object.entries(configPerEnv)) { 93 | const providerAddress = await input({ 94 | message: `Enter provider wallet address that you previously used when creating offer ${offerName} with offerId: ${offer.id}`, 95 | }); 96 | 97 | newConfigPerEnv[offerName] = { ...offer, providerAddress }; 98 | } 99 | 100 | newConfig.offers[env] = newConfigPerEnv; 101 | } 102 | 103 | return newConfig; 104 | }, 105 | } as const satisfies ConfigOptions; 106 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/providerArtifacts/providerArtifacts3.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { 19 | fluenceOldEnvToNewEnv, 20 | isFluenceEnvOld, 21 | PROVIDER_ARTIFACTS_CONFIG_FULL_FILE_NAME, 22 | type FluenceEnv, 23 | } from "../../../const.js"; 24 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 25 | 26 | import { 27 | offersConfig, 28 | type OffersConfig, 29 | type Config as PrevConfig, 30 | } from "./providerArtifacts2.js"; 31 | 32 | type Offers = Partial>; 33 | export type Config = { offers: Offers }; 34 | 35 | export default { 36 | schema: { 37 | type: "object", 38 | additionalProperties: false, 39 | properties: { 40 | offers: { 41 | type: "object", 42 | description: "Created offers", 43 | additionalProperties: false, 44 | properties: { 45 | testnet: offersConfig, 46 | custom: offersConfig, 47 | mainnet: offersConfig, 48 | local: offersConfig, 49 | stage: offersConfig, 50 | }, 51 | required: [], 52 | }, 53 | }, 54 | required: ["offers"], 55 | }, 56 | migrate(config) { 57 | const newConfig: Config = { offers: {} }; 58 | 59 | for (const [env, configPerEnv] of Object.entries(config.offers)) { 60 | if (Object.keys(configPerEnv).length === 0) { 61 | continue; 62 | } 63 | 64 | if (!isFluenceEnvOld(env)) { 65 | throw new Error( 66 | `Unreachable. Migration error. Unknown env ${env} in ${PROVIDER_ARTIFACTS_CONFIG_FULL_FILE_NAME}`, 67 | ); 68 | } 69 | 70 | newConfig.offers[fluenceOldEnvToNewEnv(env)] = configPerEnv; 71 | } 72 | 73 | return newConfig; 74 | }, 75 | } as const satisfies ConfigOptions; 76 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/providerSecrets/providerSecrets.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { genSecretKeyOrReturnExisting } from "../../../keyPairs.js"; 19 | import { 20 | ensureProviderSecretsConfigPath, 21 | getFluenceDir, 22 | } from "../../../paths.js"; 23 | import { getConfigInitFunction } from "../../initConfigNew.js"; 24 | import { type InitConfigOptions } from "../../initConfigNewTypes.js"; 25 | import type { ProviderConfig } from "../provider/provider.js"; 26 | 27 | import configOptions0, { type Config as Config0 } from "./providerSecrets0.js"; 28 | 29 | export const options: InitConfigOptions = { 30 | description: "Defines secrets config used for provider set up", 31 | options: [configOptions0], 32 | getConfigPath: ensureProviderSecretsConfigPath, 33 | getSchemaDirPath: getFluenceDir, 34 | }; 35 | 36 | export async function initNewProviderSecretsConfig( 37 | providerConfig: ProviderConfig, 38 | ) { 39 | return getConfigInitFunction(options, async () => { 40 | const { Wallet } = await import("ethers"); 41 | 42 | return { 43 | noxes: Object.fromEntries( 44 | await Promise.all( 45 | Object.keys(providerConfig.computePeers).map(async (name) => { 46 | return [ 47 | name, 48 | { 49 | networkKey: (await genSecretKeyOrReturnExisting(name)) 50 | .secretKey, 51 | signingWallet: Wallet.createRandom().privateKey, 52 | }, 53 | ] as const; 54 | }), 55 | ), 56 | ), 57 | }; 58 | })(); 59 | } 60 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/project/providerSecrets/providerSecrets0.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import type { JSONSchemaType } from "ajv"; 19 | 20 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 21 | 22 | type SecretsConfig = { 23 | networkKey: string; 24 | signingWallet: string; 25 | }; 26 | 27 | const secretesConfig = { 28 | type: "object", 29 | additionalProperties: false, 30 | description: 31 | "Secret keys for noxes. You can put it near provider config and populate it in CI", 32 | properties: { 33 | networkKey: { 34 | type: "string", 35 | description: "Network key for the nox", 36 | }, 37 | signingWallet: { 38 | type: "string", 39 | format: "hex", 40 | description: "Signing wallet for built-in decider system service in nox", 41 | }, 42 | }, 43 | required: ["networkKey", "signingWallet"], 44 | } as const satisfies JSONSchemaType; 45 | 46 | export type Config = { 47 | noxes: Record; 48 | }; 49 | 50 | export default { 51 | schema: { 52 | type: "object", 53 | additionalProperties: false, 54 | properties: { 55 | noxes: { 56 | type: "object", 57 | description: "Secret keys for noxes by name", 58 | additionalProperties: secretesConfig, 59 | properties: { noxName: secretesConfig }, 60 | required: [], 61 | }, 62 | }, 63 | required: ["noxes"], 64 | }, 65 | } as const satisfies ConfigOptions; 66 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/user/config/config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { color } from "@oclif/color"; 19 | 20 | import { commandObj, isInteractive } from "../../../commandObj.js"; 21 | import { CLI_NAME_FULL, AUTO_GENERATED } from "../../../const.js"; 22 | import { getUserConfigPath } from "../../../paths.js"; 23 | import { confirm } from "../../../prompt.js"; 24 | import { getConfigInitFunction } from "../../initConfigNew.js"; 25 | import { type InitConfigOptions } from "../../initConfigNewTypes.js"; 26 | 27 | import configOptions0, { type Config as Config0 } from "./config0.js"; 28 | import configOptions1, { type Config as Config1 } from "./config1.js"; 29 | 30 | export const options: InitConfigOptions = { 31 | description: `Defines global config for ${CLI_NAME_FULL}`, 32 | options: [configOptions0, configOptions1], 33 | getConfigPath: getUserConfigPath, 34 | }; 35 | 36 | export async function initNewUserConfig() { 37 | const userConfig = await getConfigInitFunction(options, async () => { 38 | let countlyConsent = false; 39 | 40 | if ( 41 | isInteractive && 42 | (await confirm({ 43 | message: `Help me improve ${CLI_NAME_FULL} by sending anonymous usage data. I don't collect IDs, names, or other personal data.\n${color.gray( 44 | "Metrics will help the developers know which features are useful so they can prioritize what to work on next. Cloudless Labs hosts a Countly instance to record anonymous usage data.", 45 | )}\nOK?`, 46 | })) 47 | ) { 48 | countlyConsent = true; 49 | 50 | commandObj.logToStderr( 51 | `If you change your mind later, modify "countlyConsent" property in ${await options.getConfigPath()}`, 52 | ); 53 | } 54 | 55 | return { countlyConsent, defaultSecretKeyName: AUTO_GENERATED }; 56 | })(); 57 | 58 | return userConfig; 59 | } 60 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/user/config/config0.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { CLI_NAME_FULL } from "../../../const.js"; 19 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 20 | 21 | export type Config = { 22 | countlyConsent: boolean; 23 | lastCheckForUpdates?: string; 24 | }; 25 | 26 | export default { 27 | schema: { 28 | type: "object", 29 | additionalProperties: false, 30 | properties: { 31 | countlyConsent: { 32 | type: "boolean", 33 | description: "Weather you consent to send usage data to Countly", 34 | }, 35 | lastCheckForUpdates: { 36 | type: "string", 37 | description: `DEPRECATED. It's currently advised to install CLI without using npm (See README.md: https://github.com/fluencelabs/cli?tab=readme-ov-file#installation-and-usage). Last time when ${CLI_NAME_FULL} checked for updates. Updates are checked daily unless this field is set to 'disabled'`, 38 | nullable: true, 39 | }, 40 | }, 41 | required: ["countlyConsent"], 42 | }, 43 | } as const satisfies ConfigOptions; 44 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/configs/user/config/config1.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { commandObj } from "../../../commandObj.js"; 19 | import type { ConfigOptions } from "../../initConfigNewTypes.js"; 20 | 21 | import type { Config as PrevConfig } from "./config0.js"; 22 | 23 | export type Config = { 24 | countlyConsent: boolean; 25 | defaultSecretKeyName?: string; 26 | docsInConfigs?: boolean; 27 | }; 28 | 29 | export default { 30 | schema: { 31 | type: "object", 32 | additionalProperties: false, 33 | properties: { 34 | countlyConsent: { 35 | type: "boolean", 36 | description: "Weather you consent to send usage data to Countly", 37 | }, 38 | defaultSecretKeyName: { 39 | type: "string", 40 | description: 41 | "DEPRECATED: Secret key with this name will be used by default by js-client inside CLI to run Aqua code", 42 | nullable: true, 43 | }, 44 | docsInConfigs: { 45 | type: "boolean", 46 | description: "DEPRECATED: Whether to include docs in generated configs", 47 | nullable: true, 48 | }, 49 | }, 50 | required: ["countlyConsent"], 51 | }, 52 | migrate({ lastCheckForUpdates, ...config }) { 53 | if (lastCheckForUpdates !== undefined) { 54 | commandObj.log( 55 | `Use of 'lastCheckForUpdates' field is deprecated. It's currently advised to install CLI without using npm`, 56 | ); 57 | } 58 | 59 | return config; 60 | }, 61 | } as const satisfies ConfigOptions; 62 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/countly.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { 19 | sessionEndPromise, 20 | isCountlyInitialized, 21 | } from "../errorInterceptor.js"; 22 | 23 | import { commandObj } from "./commandObj.js"; 24 | import { initNewUserConfig } from "./configs/user/config/config.js"; 25 | import { IS_DEVELOPMENT } from "./const.js"; 26 | import { ensureDir, getUserCountlyDir } from "./paths.js"; 27 | 28 | export async function initCountly(): Promise { 29 | const userCountlyDir = await getUserCountlyDir(); 30 | const userConfig = await initNewUserConfig(); 31 | 32 | if (!IS_DEVELOPMENT && userConfig.countlyConsent) { 33 | const Countly = (await import("countly-sdk-nodejs")).default; 34 | 35 | Countly.init({ 36 | app_key: "728984bc3e1aee7dd29674ee300530750b5630d8", 37 | url: "https://countly.fluence.dev/", 38 | debug: process.env.DEBUG_COUNTLY === "true", 39 | storage_path: await ensureDir(userCountlyDir), 40 | app_version: commandObj.config.version, 41 | }); 42 | 43 | Countly.begin_session(); 44 | 45 | Countly.add_event({ 46 | key: `command:${commandObj.id ?? "unknown"}`, 47 | segmentation: { 48 | userAgent: commandObj.config.userAgent, 49 | platform: commandObj.config.platform, 50 | }, 51 | }); 52 | } 53 | } 54 | 55 | export const haltCountly = async (): Promise => { 56 | if (!(await isCountlyInitialized())) { 57 | return; 58 | } 59 | 60 | const Countly = (await import("countly-sdk-nodejs")).default; 61 | Countly.end_session(); 62 | await sessionEndPromise; 63 | }; 64 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/dbg.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import debug from "debug"; 19 | 20 | export const dbg = debug("fcli:debug"); 21 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/dockerCompose.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { execPromise, type ExecPromiseArg } from "./execPromise.js"; 19 | 20 | let useDockerComposeV2: boolean | undefined; 21 | 22 | export async function dockerCompose( 23 | args: Omit & { args: string[] }, 24 | ) { 25 | if (useDockerComposeV2 === undefined) { 26 | try { 27 | await execPromise({ 28 | command: "docker", 29 | args: ["compose", "version"], 30 | }); 31 | 32 | useDockerComposeV2 = true; 33 | } catch { 34 | useDockerComposeV2 = false; 35 | } 36 | } 37 | 38 | return execPromise({ 39 | command: useDockerComposeV2 ? "docker" : "docker-compose", 40 | ...args, 41 | args: useDockerComposeV2 ? ["compose", ...args.args] : args.args, 42 | }); 43 | } 44 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/ensureChainNetwork.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { color } from "@oclif/color"; 19 | 20 | import type { ChainENV } from "../common.js"; 21 | 22 | import { commandObj } from "./commandObj.js"; 23 | import { ensureFluenceEnv } from "./resolveFluenceEnv.js"; 24 | 25 | let env: ChainENV | undefined = undefined; 26 | 27 | function setEnv(e: ChainENV): ChainENV { 28 | if (env !== e) { 29 | commandObj.logToStderr(`Using ${color.yellow(e)} blockchain environment`); 30 | } 31 | 32 | env = e; 33 | return env; 34 | } 35 | 36 | export async function ensureChainEnv(): Promise { 37 | return env === undefined ? setEnv(await ensureFluenceEnv()) : env; 38 | } 39 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/fluenceEnvPrompt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { CHAIN_ENV } from "../common.js"; 19 | 20 | import { type FluenceEnv, ENV_FLAG_NAME } from "./const.js"; 21 | import { list } from "./prompt.js"; 22 | 23 | export async function fluenceEnvPrompt( 24 | message = "Select Fluence Environment to use", 25 | defaultVal: FluenceEnv = process.env.FLUENCE_ENV, 26 | ): Promise { 27 | return list({ 28 | message, 29 | options: [...CHAIN_ENV], 30 | oneChoiceMessage() { 31 | throw new Error("Unreachable. There are multiple envs"); 32 | }, 33 | onNoChoices() { 34 | throw new Error("Unreachable. There are multiple envs"); 35 | }, 36 | default: defaultVal, 37 | flagName: ENV_FLAG_NAME, 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/generateUserProviderConfig.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { PEERS_FLAG_NAME } from "./const.js"; 19 | 20 | export type ProviderConfigArgs = { 21 | [PEERS_FLAG_NAME]?: number | undefined; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/gql/gql.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { GraphQLClient } from "graphql-request"; 19 | 20 | import { getSubgraphUrl } from "../chain/chainConfig.js"; 21 | 22 | import { getSdk as getGqlSdk, type Sdk } from "./gqlGenerated.js"; 23 | 24 | let sdk: Promise | undefined = undefined; 25 | 26 | async function getSdk() { 27 | if (sdk === undefined) { 28 | sdk = (async () => { 29 | return getGqlSdk(new GraphQLClient(await getSubgraphUrl())); 30 | })(); 31 | } 32 | 33 | return sdk; 34 | } 35 | 36 | // const DEFAULT_PAGE_LIMIT = 1000; 37 | 38 | // async function getAllPages(getter: (skip: number) => Promise) { 39 | // let result: T[] = []; 40 | // let skip = 0; 41 | // let hasMore = true; 42 | 43 | // while (hasMore) { 44 | // const res = await getter(skip); 45 | // result = result.concat(res); 46 | 47 | // if (res.length === DEFAULT_PAGE_LIMIT) { 48 | // skip = skip + DEFAULT_PAGE_LIMIT; 49 | // } else { 50 | // hasMore = false; 51 | // } 52 | // } 53 | 54 | // return result; 55 | // } 56 | 57 | export async function getOffers(id_in: string[]) { 58 | return (await getSdk()).OfferDetails({ where: { id_in, deleted: false } }); 59 | } 60 | 61 | export async function getCCIdsByHexPeerIds(hexPeerIds: string[]) { 62 | return (await getSdk()).CCIdsByPeerIds({ 63 | where: { peer_: { id_in: hexPeerIds } }, 64 | }); 65 | } 66 | 67 | export async function getCCDetails(ccIds: string[]) { 68 | return (await getSdk()).CCDetails({ where: { id_in: ccIds } }); 69 | } 70 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/gql/gqlCodegen.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { dirname, join } from "node:path"; 19 | import { fileURLToPath } from "node:url"; 20 | 21 | import type { CodegenConfig } from "@graphql-codegen/cli"; 22 | 23 | const __filename = fileURLToPath(import.meta.url); 24 | const __dirname = dirname(__filename); 25 | 26 | export default { 27 | schema: join(__dirname, "gqlSchema.json"), 28 | documents: join(__dirname, "schema.graphql"), 29 | generates: { 30 | [join(__dirname, "gqlGenerated.ts")]: { 31 | plugins: [ 32 | "typescript", 33 | "typescript-operations", 34 | "typescript-graphql-request", 35 | ], 36 | config: { 37 | /** 38 | * Fail if there are unknown scalars (that are mapped to `any` type) 39 | */ 40 | strictScalars: true, 41 | /** 42 | * The Graph custom scalars 43 | */ 44 | scalars: { 45 | BigInt: "string", 46 | BigDecimal: "string", 47 | Bytes: "string", 48 | Int8: "number", 49 | Timestamp: "number", 50 | }, 51 | /** 52 | * This makes import look like `import { gql } from "graphql-tag"` 53 | * and not `import gql from "graphql-tag"`, fixing "This expression is not callable" 54 | */ 55 | gqlImport: "graphql-tag#gql", 56 | /** 57 | * Import types with `import type { ... }` 58 | */ 59 | useTypeImports: true, 60 | emitLegacyCommonJSImports: false, 61 | enumsAsTypes: true, 62 | }, 63 | }, 64 | }, 65 | } satisfies CodegenConfig; 66 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/gql/schema.graphql: -------------------------------------------------------------------------------- 1 | query OfferDetails($where: Offer_filter) { 2 | offers(where: $where) { 3 | id 4 | createdAt 5 | updatedAt 6 | pricePerEpoch 7 | paymentToken { 8 | id 9 | } 10 | computeUnitsTotal 11 | computeUnitsAvailable 12 | provider { 13 | id 14 | } 15 | offerResources { 16 | price 17 | resourceDescription { 18 | id 19 | type 20 | metadata 21 | } 22 | } 23 | peers(where: { deleted: false }) { 24 | id 25 | computeUnits(first: 1000, where: { deleted: false }) { 26 | id 27 | worker { 28 | id 29 | } 30 | } 31 | peerResources { 32 | maxSupply 33 | details 34 | resourceDescription { 35 | id 36 | type 37 | metadata 38 | } 39 | } 40 | } 41 | datacenter { 42 | id 43 | countryCode 44 | cityCode 45 | cityIndex 46 | tier 47 | certifications 48 | } 49 | } 50 | } 51 | 52 | query CCIdsByPeerIds($where: CapacityCommitment_filter) { 53 | capacityCommitments( 54 | where: $where 55 | orderBy: createdAt 56 | # only get the last cc for each peer 57 | orderDirection: desc 58 | first: 1 59 | ) { 60 | id 61 | peer { 62 | id 63 | } 64 | } 65 | } 66 | 67 | query CCDetails($where: CapacityCommitment_filter) { 68 | capacityCommitments(where: $where) { 69 | id 70 | ccRewardsWithdrawn 71 | dealStakerRewardsWithdrawn 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/aliasesText.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { CLI_NAME } from "../const.js"; 19 | 20 | export function aliasesText(this: { hiddenAliases: string[] }) { 21 | if (this.hiddenAliases.length === 0) { 22 | return ""; 23 | } 24 | 25 | return `. Alias${this.hiddenAliases.length === 1 ? "" : "es"}: ${this.hiddenAliases 26 | .map((alias) => { 27 | return `${CLI_NAME} ${alias.split(":").join(" ")}`; 28 | }) 29 | .join(", ")}`; 30 | } 31 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/bigintOps.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | export function secondsToDate(bigSec: bigint | number): Date { 19 | return new Date(Number(bigSec) * 1000); 20 | } 21 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/getIsInteractive.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { IS_TTY, NO_INPUT_FLAG_NAME } from "../const.js"; 19 | 20 | export const getIsInteractive = (flags: { 21 | [NO_INPUT_FLAG_NAME]: boolean; 22 | }): boolean => { 23 | return IS_TTY && !flags[NO_INPUT_FLAG_NAME]; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/getPeerIdFromSecretKey.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { base64ToUint8Array } from "../keyPairs.js"; 19 | 20 | export async function getPeerIdFromSecretKey(secretKey: string) { 21 | const { generateKeyPairFromSeed } = await import("@libp2p/crypto/keys"); 22 | const { createFromPrivKey } = await import("@libp2p/peer-id-factory"); 23 | 24 | const key = await generateKeyPairFromSeed( 25 | "Ed25519", 26 | base64ToUint8Array(secretKey), 27 | 256, 28 | ); 29 | 30 | // eslint-disable-next-line no-restricted-syntax 31 | return (await createFromPrivKey(key)).toString(); 32 | } 33 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/logAndFail.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | export function logAndFail(unknown: unknown): never { 19 | // eslint-disable-next-line no-console 20 | console.dir(unknown, { colors: true, depth: null }); 21 | throw new Error("Stopped command execution after logging"); 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/recursivelyFindFile.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { access } from "node:fs/promises"; 19 | import { dirname, join } from "node:path"; 20 | 21 | export const recursivelyFindFile = async ( 22 | fileName: string, 23 | dirPath: string, 24 | ): Promise => { 25 | let currentDirPath = dirPath; 26 | 27 | let filePathToReturn: undefined | string | null; 28 | 29 | while (filePathToReturn === undefined) { 30 | const filePath = join(currentDirPath, fileName); 31 | 32 | try { 33 | await access(filePath); 34 | filePathToReturn = filePath; 35 | } catch { 36 | const parentDir = dirname(currentDirPath); 37 | 38 | if (parentDir === currentDirPath) { 39 | filePathToReturn = null; 40 | continue; 41 | } 42 | 43 | currentDirPath = parentDir; 44 | } 45 | } 46 | 47 | return filePathToReturn; 48 | }; 49 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/setTryTimeout.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { color } from "@oclif/color"; 19 | 20 | import { commandObj } from "../commandObj.js"; 21 | import { dbg } from "../dbg.js"; 22 | 23 | import { stringifyUnknown } from "./stringifyUnknown.js"; 24 | import { numToStr } from "./typesafeStringify.js"; 25 | 26 | export async function setTryTimeout( 27 | message: string, 28 | callbackToTry: () => T | Promise, 29 | errorHandler: (error: unknown) => U, 30 | msToTryFor: number, 31 | msBetweenTries = 1000, 32 | failCondition?: (error: unknown) => boolean, 33 | ): Promise { 34 | const yellowMessage = color.yellow(message); 35 | let isTimeoutRunning = true; 36 | 37 | const timeout = setTimeout(() => { 38 | isTimeoutRunning = false; 39 | }, msToTryFor); 40 | 41 | let error: unknown; 42 | let attemptCounter = 1; 43 | let isTrying = true; 44 | 45 | while (isTrying) { 46 | isTrying = isTimeoutRunning; 47 | 48 | try { 49 | dbg(`Trying to ${yellowMessage}`); 50 | const res = await callbackToTry(); 51 | 52 | if (attemptCounter > 1) { 53 | commandObj.logToStderr( 54 | `Succeeded to ${yellowMessage} after ${numToStr(attemptCounter)} attempts`, 55 | ); 56 | } else { 57 | dbg(`Succeeded to ${yellowMessage}`); 58 | } 59 | 60 | clearTimeout(timeout); 61 | isTrying = false; 62 | return res; 63 | } catch (e) { 64 | if (failCondition !== undefined && failCondition(e)) { 65 | clearTimeout(timeout); 66 | return errorHandler(e); 67 | } 68 | 69 | const errorString = stringifyUnknown(e); 70 | const previousErrorString = stringifyUnknown(error); 71 | 72 | if (errorString === previousErrorString) { 73 | commandObj.logToStderr( 74 | `Attempt #${numToStr( 75 | attemptCounter, 76 | )} to ${yellowMessage} failed with the same error`, 77 | ); 78 | } else { 79 | const retryMessage = isTrying ? ". Going to retry" : ""; 80 | commandObj.logToStderr(`Failing to ${yellowMessage}${retryMessage}`); 81 | dbg(`Reason: ${stringifyUnknown(e)}`); 82 | } 83 | 84 | error = e; 85 | attemptCounter++; 86 | } 87 | 88 | await new Promise((resolve) => { 89 | setTimeout(resolve, msBetweenTries); 90 | }); 91 | } 92 | 93 | return errorHandler(error); 94 | } 95 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/spinner.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { color } from "@oclif/color"; 19 | 20 | import { commandObj } from "../commandObj.js"; 21 | 22 | export function startSpinner(message: string) { 23 | commandObj.logToStderr(`${color.yellow("#")} ${message}...`); 24 | } 25 | 26 | export function stopSpinner(message: string | undefined = "done") { 27 | commandObj.logToStderr(message); 28 | } 29 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/stringifyUnknown.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { AssertionError } from "assert"; 19 | 20 | import { CLIError } from "@oclif/core/errors"; 21 | 22 | /** 23 | * Used for error stringification cause one can throw anything in js (not only errors) 24 | * also used for e.g. debug logs or "unreachable error" messages where we don't necessarily care much about the output as long as it's somewhat readable. 25 | * it would be good to have two functions for this each with a more clear purpose for existence and used accordingly TODO: DXJ-763 26 | */ 27 | 28 | export function stringifyUnknown(unknown: unknown): string { 29 | try { 30 | if (typeof unknown === "string") { 31 | return unknown; 32 | } 33 | 34 | if (unknown instanceof CLIError || unknown instanceof AssertionError) { 35 | // eslint-disable-next-line no-restricted-syntax 36 | return String(unknown); 37 | } 38 | 39 | if (unknown instanceof Error) { 40 | const errorMessage = 41 | typeof unknown.stack === "string" && 42 | unknown.stack.includes(unknown.message) 43 | ? unknown.stack 44 | : `${unknown.message}${unknown.stack === undefined ? "" : `\n${unknown.stack}`}`; 45 | 46 | const otherErrorProperties = Object.getOwnPropertyNames(unknown).filter( 47 | (p) => { 48 | return p !== "message" && p !== "stack"; 49 | }, 50 | ); 51 | 52 | return `${errorMessage}${ 53 | otherErrorProperties.length > 0 54 | ? `\n${JSON.stringify(unknown, otherErrorProperties, 2)}` 55 | : "" 56 | }`; 57 | } 58 | 59 | if (unknown === undefined) { 60 | return "undefined"; 61 | } 62 | 63 | return JSON.stringify(unknown, null, 2); 64 | } catch { 65 | // eslint-disable-next-line no-restricted-syntax 66 | return String(unknown); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/typesafeStringify.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { URL } from "node:url"; 19 | /* eslint-disable no-restricted-syntax */ 20 | 21 | export function numToStr(num: number): string { 22 | return num.toString(); 23 | } 24 | 25 | export function bigintToStr(num: bigint): string { 26 | return num.toString(); 27 | } 28 | 29 | export function boolToStr(bool: boolean): string { 30 | return bool ? "true" : "false"; 31 | } 32 | 33 | export function bufferToBase64(buffer: Buffer): string { 34 | return buffer.toString("base64"); 35 | } 36 | 37 | export function bufferToStr(buffer: Buffer): string { 38 | return buffer.toString(); 39 | } 40 | 41 | export function urlToStr(url: URL) { 42 | return url.toString(); 43 | } 44 | 45 | export function nullableToString(value: null | undefined): string { 46 | return value === null ? "null" : "undefined"; 47 | } 48 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/helpers/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { access } from "node:fs/promises"; 19 | 20 | import { numToStr } from "./typesafeStringify.js"; 21 | 22 | export function commaSepStrToArr(commaSepStr: string) { 23 | return commaSepStr 24 | .split(",") 25 | .map((s) => { 26 | return s.trim(); 27 | }) 28 | .filter((s) => { 29 | return s !== ""; 30 | }); 31 | } 32 | 33 | function flagToArg( 34 | flagName: string, 35 | flagValue: string | number | boolean | undefined, 36 | ): string[] { 37 | if (flagValue === undefined || flagValue === false) { 38 | return []; 39 | } 40 | 41 | const flag = `-${flagName.length > 1 ? "-" : ""}${flagName}`; 42 | 43 | if (flagValue === true) { 44 | return [flag]; 45 | } 46 | 47 | return [ 48 | flag, 49 | typeof flagValue === "number" ? numToStr(flagValue) : flagValue, 50 | ]; 51 | } 52 | 53 | export type Flags = Record< 54 | string, 55 | string | number | boolean | undefined | Array 56 | >; 57 | 58 | export const flagsToArgs = (flags: Flags): string[] => { 59 | return Object.entries(flags) 60 | .map(([flagName, flagValue]): Array => { 61 | return Array.isArray(flagValue) 62 | ? flagValue.map((value): string[] => { 63 | return flagToArg(flagName, value); 64 | }) 65 | : [flagToArg(flagName, flagValue)]; 66 | }) 67 | .flat(2); 68 | }; 69 | 70 | export function removeProperties( 71 | obj: Record, 72 | isPropertyToRemove: (arg: [key: string, value: unknown]) => boolean, 73 | ): Record { 74 | return Object.fromEntries( 75 | Object.entries(obj).filter(([key, value]) => { 76 | return !isPropertyToRemove([key, value]); 77 | }), 78 | ); 79 | } 80 | 81 | export function splitErrorsAndResults( 82 | array: Array, 83 | splitter: ( 84 | v: T, 85 | i: number, 86 | ) => { error: NonNullable } | { result: NonNullable }, 87 | ): [NonNullable[], NonNullable[]] { 88 | const errors: Array> = []; 89 | const results: Array> = []; 90 | 91 | for (const [i, item] of Object.entries(array)) { 92 | const splitted = splitter(item, Number(i)); 93 | 94 | if ("error" in splitted) { 95 | errors.push(splitted.error); 96 | } else { 97 | results.push(splitted.result); 98 | } 99 | } 100 | 101 | return [errors, results]; 102 | } 103 | 104 | export async function pathExists(path: string) { 105 | try { 106 | await access(path); 107 | return true; 108 | } catch { 109 | return false; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/keyPairs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { readFile, writeFile } from "node:fs/promises"; 19 | import { relative } from "node:path"; 20 | 21 | import { bufferToBase64 } from "./helpers/typesafeStringify.js"; 22 | import { ensureFluenceSecretsFilePath, getFluenceDir } from "./paths.js"; 23 | 24 | export async function genSecretKeyOrReturnExisting(name: string) { 25 | const fluenceDir = getFluenceDir(); 26 | const filePath = await ensureFluenceSecretsFilePath(name); 27 | let secretKey; 28 | 29 | try { 30 | secretKey = await readFile(filePath, "utf8"); 31 | } catch { 32 | secretKey = await genSecretKeyString(); 33 | await writeFile(filePath, secretKey, "utf8"); 34 | } 35 | 36 | return { 37 | name, 38 | relativeSecretFilePath: relative(fluenceDir, filePath), 39 | secretKey, 40 | } as const; 41 | } 42 | 43 | async function genSecretKeyString(): Promise { 44 | const { generateKeyPair } = await import("@libp2p/crypto/keys"); 45 | 46 | return bufferToBase64( 47 | Buffer.from((await generateKeyPair("Ed25519")).marshal().subarray(0, 32)), 48 | ); 49 | } 50 | 51 | export function base64ToUint8Array(base64: string) { 52 | return new Uint8Array(Buffer.from(base64, "base64")); 53 | } 54 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/setupEnvironment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { isAbsolute } from "node:path"; 19 | 20 | import { CONTRACTS_ENV } from "@fluencelabs/deal-ts-clients"; 21 | import dotenv from "dotenv"; 22 | 23 | export const FLUENCE_ENV = "FLUENCE_ENV"; 24 | export const DEBUG_COUNTLY = "DEBUG_COUNTLY"; 25 | export const FLUENCE_USER_DIR = "FLUENCE_USER_DIR"; 26 | export const CI = "CI"; 27 | 28 | dotenv.config(); 29 | 30 | const resolveEnvVariable = ( 31 | variableName: string, 32 | isValid: (v: unknown) => v is T, 33 | ): T => { 34 | const variable = process.env[variableName]; 35 | 36 | if (!isValid(variable)) { 37 | throw new Error( 38 | variable === undefined 39 | ? `Environment variable not set: ${variableName}` 40 | : `Invalid environment variable: ${variableName}="${variable}"`, 41 | ); 42 | } 43 | 44 | return variable; 45 | }; 46 | 47 | const setEnvVariable = ( 48 | variableName: string, 49 | isValid: (v: unknown) => v is T, 50 | defaultVariable?: T, 51 | ) => { 52 | const variable = process.env[variableName]; 53 | 54 | if (variable === undefined) { 55 | if (defaultVariable !== undefined) { 56 | process.env[variableName] = defaultVariable; 57 | } 58 | 59 | return; 60 | } 61 | 62 | process.env[variableName] = resolveEnvVariable(variableName, isValid); 63 | }; 64 | 65 | const isTrueOrFalseString = (v: unknown): v is "true" | "false" => { 66 | return v === "true" || v === "false"; 67 | }; 68 | 69 | const isAbsolutePath = (v: unknown): v is string => { 70 | return typeof v === "string" && isAbsolute(v); 71 | }; 72 | 73 | setEnvVariable( 74 | FLUENCE_ENV, 75 | (val): val is (typeof CONTRACTS_ENV)[number] => { 76 | return CONTRACTS_ENV.some((v) => { 77 | return v === val; 78 | }); 79 | }, 80 | "local", 81 | ); 82 | 83 | setEnvVariable(DEBUG_COUNTLY, isTrueOrFalseString, "false"); 84 | setEnvVariable(CI, isTrueOrFalseString, "false"); 85 | setEnvVariable(FLUENCE_USER_DIR, isAbsolutePath); 86 | -------------------------------------------------------------------------------- /packages/cli/package/src/lib/typeHelpers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | /** 19 | * Makes all properties in the object to be NOT readonly 20 | * Doesn't work recursively 21 | * 22 | * @example 23 | * const readonlyObject: Readonly<{a: number}> = { a: 1 }; 24 | * const mutableObject: Mutable = readonlyObject; 25 | * mutableObject.a = 2; 26 | */ 27 | export type Mutable = { 28 | -readonly [Key in keyof Type]: Type[Key]; 29 | }; 30 | 31 | /** 32 | * Makes particular object properties to be required 33 | * 34 | * @example 35 | * const object: { a?: number, b?: string, c?: boolean } = {}; 36 | * const requiredObject: WithRequired = { a: 1, b: "b" }; 37 | */ 38 | export type WithRequired = T & { [P in K]-?: T[P] }; 39 | export type Required = WithRequired; 40 | 41 | export type Flags = Record< 42 | T, 43 | string | number | boolean | Array 44 | >; 45 | 46 | export type OptionalFlags = Partial< 47 | Record> 48 | >; 49 | 50 | /** 51 | * Useful for debugging. Merges any compound type into a final flat object type 52 | */ 53 | export type Prettify = { 54 | [K in keyof T]: T[K]; 55 | } & {}; 56 | -------------------------------------------------------------------------------- /packages/cli/package/src/reset.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import "@total-typescript/ts-reset"; 19 | -------------------------------------------------------------------------------- /packages/cli/package/src/versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "protocolVersion": 2, 3 | "chain-rpc": "docker.fluence.dev/chain-rpc:update-deal-interface-c153307-7773-1", 4 | "chain-deploy-script": "docker.fluence.dev/chain-deploy-script:update-deal-interface-c153307-7773-1", 5 | "subgraph-deploy-script": "docker.fluence.dev/subgraph-deploy-script:update-deal-interface-c153307-7773-1" 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli/package/src/versions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import snakeCase from "lodash-es/snakeCase.js"; 19 | 20 | import versionsJSON from "./versions.json" with { type: "json" }; 21 | 22 | // Don't know how to do this transformation without type assertion. 23 | // It is pretty simple so it is safe 24 | // eslint-disable-next-line @typescript-eslint/consistent-type-assertions 25 | export const versions = override(versionsJSON, "FCLI_V") as typeof versionsJSON; 26 | 27 | type AllowedValues = string | number | boolean; 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-empty-object-type 30 | interface RecToOverride extends Record {} 31 | 32 | /** 33 | * Override versions using env variables 34 | * @param rec Record to override 35 | * @param prefix Prefix for env variables 36 | * @returns Overridden record 37 | */ 38 | function override(rec: RecToOverride, prefix: string): RecToOverride { 39 | return Object.fromEntries( 40 | Object.entries(rec).map(([name, version]) => { 41 | const envVarName = `${prefix}_${snakeCase(name).toUpperCase()}`; 42 | 43 | if (typeof version !== "object") { 44 | const versionFromEnv = process.env[envVarName]; 45 | 46 | const overriddenVersion = 47 | versionFromEnv === undefined || versionFromEnv === "" 48 | ? version 49 | : versionFromEnv; 50 | 51 | return [name, overriddenVersion]; 52 | } 53 | 54 | return [name, override(version, envVarName)]; 55 | }), 56 | ); 57 | } 58 | -------------------------------------------------------------------------------- /packages/cli/package/test/helpers/commonWithSetupTests.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import assert from "node:assert"; 19 | import { access, readdir } from "node:fs/promises"; 20 | import { arch, platform } from "node:os"; 21 | import { join } from "node:path"; 22 | 23 | import { CustomColors } from "@oclif/color"; 24 | import { x as tar } from "tar"; 25 | 26 | import { CLI_NAME } from "../../src/lib/const.js"; 27 | import { execPromise, type ExecPromiseArg } from "../../src/lib/execPromise.js"; 28 | import { flagsToArgs } from "../../src/lib/helpers/utils.js"; 29 | 30 | type CliArg = { 31 | args?: ExecPromiseArg["args"]; 32 | flags?: ExecPromiseArg["flags"]; 33 | cwd?: string; 34 | timeout?: number; 35 | }; 36 | 37 | const pathToDistDir = join(process.cwd(), "dist"); 38 | const pathToCliDir = join(pathToDistDir, CLI_NAME); 39 | 40 | const files = await readdir(pathToDistDir); 41 | 42 | const archiveWithCLIFileName = files.find((name) => { 43 | return ( 44 | name.startsWith(CLI_NAME) && name.endsWith(`${platform()}-${arch()}.tar.gz`) 45 | ); 46 | }); 47 | 48 | assert( 49 | archiveWithCLIFileName !== undefined, 50 | "After successful build there should be an archive with CLI in the dist directory", 51 | ); 52 | 53 | try { 54 | await access(pathToCliDir); 55 | } catch { 56 | await tar({ 57 | cwd: pathToDistDir, 58 | file: join(pathToDistDir, archiveWithCLIFileName), 59 | }); 60 | } 61 | 62 | const pathToBinDir = join(pathToCliDir, "bin"); 63 | const pathToCliRunJS = join(pathToBinDir, "run.js"); 64 | const pathToNodeJS = join(pathToBinDir, "node"); 65 | 66 | export const fluence = async ({ 67 | args = [], 68 | flags, 69 | cwd = process.cwd(), 70 | timeout = 1000 * 60 * 4, // 4 minutes, 71 | }: CliArg): ReturnType => { 72 | let res: string; 73 | 74 | args = ["--no-warnings", "--no-deprecation", pathToCliRunJS, ...args]; 75 | 76 | flags = { 77 | "no-input": true, 78 | ...flags, 79 | }; 80 | 81 | console.log( 82 | CustomColors.addon( 83 | `${cwd} % ${pathToNodeJS} ${args.join(" ")} ${flagsToArgs(flags).join( 84 | " ", 85 | )}`, 86 | ), 87 | ); 88 | 89 | try { 90 | res = await execPromise({ 91 | command: pathToNodeJS, 92 | args, 93 | flags, 94 | options: { cwd }, 95 | timeout, 96 | }); 97 | } catch (err) { 98 | if (err instanceof Error) { 99 | throw new Error( 100 | // CHECK THE STACK TRACE BELOW TO SEE THE ERROR ORIGIN 101 | err.message, 102 | ); 103 | } 104 | 105 | throw err; 106 | } 107 | 108 | return res; 109 | }; 110 | -------------------------------------------------------------------------------- /packages/cli/package/test/helpers/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { FLUENCE_ENV } from "../../src/lib/setupEnvironment.js"; 19 | 20 | export const fluenceEnv = process.env[FLUENCE_ENV]; 21 | export const CC_DURATION_SECONDS = 30; 22 | -------------------------------------------------------------------------------- /packages/cli/package/test/helpers/paths.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { join } from "node:path"; 19 | 20 | export const initializedTemplatePath = join( 21 | "test", 22 | "tmp", 23 | "templates", 24 | "provider", 25 | ); 26 | -------------------------------------------------------------------------------- /packages/cli/package/test/helpers/sharedSteps.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { cp, rm } from "node:fs/promises"; 19 | 20 | import { initializedTemplatePath } from "./paths.js"; 21 | 22 | export async function initializeTemplate(cwd: string): Promise { 23 | await rm(cwd, { recursive: true, force: true }); 24 | await cp(initializedTemplatePath, cwd, { recursive: true }); 25 | } 26 | -------------------------------------------------------------------------------- /packages/cli/package/test/helpers/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import core from "@actions/core"; 19 | import { test } from "vitest"; 20 | 21 | export const sleepSeconds = (s: number) => { 22 | return new Promise((resolve) => { 23 | return setTimeout(resolve, s * 1000); 24 | }); 25 | }; 26 | 27 | export function wrappedTest( 28 | name: string, 29 | fn: ( 30 | context: Parameters[2]>>[0], 31 | ) => Promise, 32 | ) { 33 | test(name, async (...args) => { 34 | core.startGroup(name); 35 | await fn(...args); 36 | core.endGroup(); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /packages/cli/package/test/setup/generateTemplates.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { rm, mkdir } from "fs/promises"; 19 | 20 | import { initializedTemplatePath } from "../helpers/paths.js"; 21 | 22 | await rm(initializedTemplatePath, { force: true, recursive: true }); 23 | await mkdir(initializedTemplatePath, { recursive: true }); 24 | -------------------------------------------------------------------------------- /packages/cli/package/test/setup/localUp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { fluence } from "../helpers/commonWithSetupTests.js"; 19 | import { fluenceEnv } from "../helpers/constants.js"; 20 | import { initializedTemplatePath } from "../helpers/paths.js"; 21 | 22 | if (fluenceEnv === "local") { 23 | await fluence({ 24 | args: ["local", "up"], 25 | flags: { "no-set-up": true }, 26 | cwd: initializedTemplatePath, 27 | timeout: 1000 * 60 * 5, // 5 minutes 28 | }); 29 | } 30 | 31 | await fluence({ 32 | args: ["provider", "init"], 33 | flags: { env: fluenceEnv, "no-input": true }, 34 | cwd: initializedTemplatePath, 35 | }); 36 | -------------------------------------------------------------------------------- /packages/cli/package/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "rootDir": "../" 6 | }, 7 | "include": ["../src/**/*", "../test/**/*"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli/package/tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true 5 | }, 6 | "include": ["./**/*"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/cli/package/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/strictest/tsconfig", "@tsconfig/node22/tsconfig"], 3 | "compilerOptions": { 4 | "importHelpers": true, 5 | "outDir": "dist", 6 | "rootDir": "src", 7 | "moduleResolution": "NodeNext", 8 | "module": "NodeNext", 9 | "resolveJsonModule": true, 10 | "verbatimModuleSyntax": true 11 | }, 12 | "include": ["src/**/*"], 13 | "files": ["src/environment.d.ts", "src/types.d.ts", "src/reset.d.ts"], 14 | "types": ["node"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/package/vitest.config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import { defineConfig } from "vitest/dist/config.js"; 19 | 20 | export default defineConfig({ 21 | test: { 22 | testTimeout: 1000 * 60 * 5, // 5 minutes, 23 | fileParallelism: false, 24 | bail: 1, 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /packages/common/eslint.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | // @ts-check 19 | 20 | import { dirname, join } from "path"; 21 | import { fileURLToPath } from "url"; 22 | 23 | import repoEslintConfigCommon from "@repo/eslint-config/common.js"; 24 | import tseslint from "typescript-eslint"; 25 | 26 | const __filename = fileURLToPath(import.meta.url); 27 | const __dirname = dirname(__filename); 28 | 29 | export default tseslint.config( 30 | ...repoEslintConfigCommon, 31 | { 32 | languageOptions: { 33 | parserOptions: { 34 | project: [join(__dirname, "tsconfig.json")], 35 | }, 36 | }, 37 | }, 38 | { 39 | ignores: ["dist/**", "eslint.config.js"], 40 | }, 41 | ); 42 | -------------------------------------------------------------------------------- /packages/common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/common", 3 | "license": "AGPL-3.0", 4 | "version": "0.0.0", 5 | "type": "module", 6 | "exports": { 7 | ".": { 8 | "types": "./src/index.ts", 9 | "default": "./dist/index.js" 10 | } 11 | }, 12 | "scripts": { 13 | "build": "tsc", 14 | "lint-fix": "eslint . --fix", 15 | "on-each-commit": "yarn lint-fix" 16 | }, 17 | "devDependencies": { 18 | "@total-typescript/ts-reset": "0.5.1", 19 | "@tsconfig/strictest": "2.0.5", 20 | "eslint": "9.3.0", 21 | "ethers": "6.7.1", 22 | "react": "18.2.0", 23 | "typescript": "5.4.5", 24 | "typescript-eslint": "7.11.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/common/src/reset.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import "@total-typescript/ts-reset"; 19 | -------------------------------------------------------------------------------- /packages/common/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/strictest/tsconfig", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist", 6 | "rootDir": "src", 7 | "moduleResolution": "nodenext", 8 | "module": "nodenext", 9 | "resolveJsonModule": true, 10 | "lib": ["es2023"] 11 | }, 12 | "include": ["src/**/*"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/eslint-config/README.md: -------------------------------------------------------------------------------- 1 | # `@repo/eslint-config` 2 | 3 | Collection of internal eslint configurations. 4 | -------------------------------------------------------------------------------- /packages/eslint-config/license-header.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | -------------------------------------------------------------------------------- /packages/eslint-config/node.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | // @ts-check 19 | 20 | import commonEslintConfig from "./common.js"; 21 | 22 | import globals from "globals"; 23 | import tseslint from "typescript-eslint"; 24 | 25 | export default tseslint.config(...commonEslintConfig, { 26 | languageOptions: { 27 | globals: { ...globals.node }, 28 | parserOptions: { 29 | project: true, 30 | }, 31 | }, 32 | rules: { 33 | "import/extensions": ["error", "always"], 34 | }, 35 | }); 36 | -------------------------------------------------------------------------------- /packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/eslint-config", 3 | "license": "AGPL-3.0", 4 | "type": "module", 5 | "version": "0.0.0", 6 | "private": true, 7 | "files": [ 8 | "license-header.js", 9 | "common.js", 10 | "node.js" 11 | ], 12 | "devDependencies": { 13 | "@eslint/compat": "1.0.1", 14 | "eslint": "9.3.0", 15 | "eslint-config-prettier": "9.1.0", 16 | "eslint-plugin-import": "2.29.1", 17 | "eslint-plugin-license-header": "0.6.1", 18 | "eslint-plugin-only-warn": "1.1.0", 19 | "eslint-plugin-react": "7.34.2", 20 | "eslint-plugin-react-hooks": "4.6.2", 21 | "eslint-plugin-unused-imports": "3.2.0", 22 | "globals": "15.1.0", 23 | "typescript": "5.4.5", 24 | "typescript-eslint": "7.10.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/eslint-config/react.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | // @ts-nocheck 19 | 20 | import eslintPluginReact from "eslint-plugin-react"; 21 | import eslintPluginReactHooks from "eslint-plugin-react-hooks"; 22 | import { fixupPluginRules } from "@eslint/compat"; 23 | 24 | import commonEslintConfig from "./common.js"; 25 | 26 | import tseslint from "typescript-eslint"; 27 | 28 | export default tseslint.config(...commonEslintConfig, { 29 | plugins: { 30 | react: fixupPluginRules(eslintPluginReact), 31 | "react-hooks": fixupPluginRules(eslintPluginReactHooks), 32 | }, 33 | rules: { 34 | "react/void-dom-elements-no-children": "error", 35 | "react-hooks/rules-of-hooks": "error", 36 | "react-hooks/exhaustive-deps": "error", 37 | curly: ["error", "all"], 38 | }, 39 | }); 40 | -------------------------------------------------------------------------------- /rename-packed.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluence CLI 3 | * Copyright (C) 2024 Fluence DAO 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Affero General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | // @ts-check 19 | import { rename, readdir } from "fs/promises"; 20 | import { exec } from "child_process"; 21 | import { promisify } from "util"; 22 | import cliPackageJSON from "./packages/cli/package/package.json" with { type: "json" }; 23 | /* 24 | This script renames the packed files in the dist folder to include 25 | the current commit hash, cause there might be a different commit hash in the cache 26 | */ 27 | const { stdout: commitHash } = await promisify(exec)( 28 | "git rev-parse --short HEAD", 29 | ); 30 | const common = `${cliPackageJSON.oclif.bin}-v${cliPackageJSON.version}`; 31 | const DIST_PATH = "./packages/cli/package/dist/"; 32 | await Promise.all( 33 | (await readdir(DIST_PATH)) 34 | .filter((file) => file.startsWith(common)) 35 | .map((fileName) => { 36 | const [, , , ...rest] = fileName.split("-"); 37 | const newFileName = [common, commitHash.trim(), ...rest].join("-"); 38 | if (fileName === newFileName) { 39 | return; 40 | } 41 | console.log(`Renaming ${fileName} to ${newFileName}`); 42 | return rename(`${DIST_PATH}${fileName}`, `${DIST_PATH}${newFileName}`); 43 | }), 44 | ); 45 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "tasks": { 4 | "install-yarn-dependencies": { 5 | "inputs": [ 6 | "package/package.json", 7 | "package/yarn.lock", 8 | "package/.yarnrc.yml" 9 | ], 10 | "outputs": ["package/node_modules/**"] 11 | }, 12 | "gen-gql-schema": { 13 | "dependsOn": ["install-yarn-dependencies"], 14 | "inputs": [ 15 | "package/src/lib/configs/project/chainContainers.ts", 16 | "package/src/genGqlSchema.ts", 17 | "package/src/versions.json" 18 | ], 19 | "outputs": ["package/src/lib/gql/gqlSchema.json"] 20 | }, 21 | "gql-codegen": { 22 | "dependsOn": ["gen-gql-schema"], 23 | "inputs": [ 24 | "package/src/lib/gql/gqlCodegen.ts", 25 | "package/src/lib/gql/schema.graphql" 26 | ], 27 | "outputs": ["package/src/lib/gql/gqlGenerated.ts"] 28 | }, 29 | "before-build": { 30 | "dependsOn": ["install-yarn-dependencies", "^build"], 31 | "inputs": [ 32 | "package/src/beforeBuild.ts", 33 | "package/src/versions.json", 34 | "package/src/versions.ts" 35 | ], 36 | "outputs": ["package/src/versions/**", "package/src/common.ts"] 37 | }, 38 | "build": { 39 | "dependsOn": ["^build", "before-build", "gql-codegen"], 40 | "outputs": ["dist/**", "package/dist/**"] 41 | }, 42 | "on-each-commit": { 43 | "dependsOn": ["^build", "build"] 44 | }, 45 | "pack-ci": { 46 | "dependsOn": ["build"], 47 | "outputs": ["package/dist/**"] 48 | }, 49 | "pack-linux-x64": { 50 | "dependsOn": ["build"], 51 | "outputs": ["package/dist/**"] 52 | }, 53 | "pack-darwin-x64": { 54 | "dependsOn": ["build"], 55 | "outputs": ["package/dist/**"] 56 | }, 57 | "pack-darwin-arm64": { 58 | "dependsOn": ["build"], 59 | "outputs": ["package/dist/**"] 60 | }, 61 | "pack-win32-x64": { 62 | "dependsOn": ["build"], 63 | "outputs": ["package/dist/**"] 64 | } 65 | } 66 | } 67 | --------------------------------------------------------------------------------