├── .eslintrc.json ├── .gitattributes ├── .github ├── pull_request_template.md └── workflows │ ├── auto-approve.yml │ ├── build.yml │ ├── pull-request-lint.yml │ ├── release.yml │ └── upgrade-main.yml ├── .gitignore ├── .mergify.yml ├── .npmignore ├── .projen ├── deps.json ├── files.json └── tasks.json ├── .projenrc.ts ├── API.md ├── API.md.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples ├── python │ └── ethereum.py └── typescript │ └── ethereum.ts ├── package.json ├── src ├── index.ts ├── node.ts └── utilities.ts ├── test └── node.test.ts ├── tsconfig.dev.json └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "env": { 4 | "jest": true, 5 | "node": true 6 | }, 7 | "root": true, 8 | "plugins": [ 9 | "@typescript-eslint", 10 | "import", 11 | "@stylistic" 12 | ], 13 | "parser": "@typescript-eslint/parser", 14 | "parserOptions": { 15 | "ecmaVersion": 2018, 16 | "sourceType": "module", 17 | "project": "./tsconfig.dev.json" 18 | }, 19 | "extends": [ 20 | "plugin:import/typescript" 21 | ], 22 | "settings": { 23 | "import/parsers": { 24 | "@typescript-eslint/parser": [ 25 | ".ts", 26 | ".tsx" 27 | ] 28 | }, 29 | "import/resolver": { 30 | "node": {}, 31 | "typescript": { 32 | "project": "./tsconfig.dev.json", 33 | "alwaysTryTypes": true 34 | } 35 | } 36 | }, 37 | "ignorePatterns": [ 38 | "*.js", 39 | "*.d.ts", 40 | "node_modules/", 41 | "*.generated.ts", 42 | "coverage", 43 | "!.projenrc.ts", 44 | "!projenrc/**/*.ts" 45 | ], 46 | "rules": { 47 | "@stylistic/indent": [ 48 | "error", 49 | 2 50 | ], 51 | "@stylistic/quotes": [ 52 | "error", 53 | "single", 54 | { 55 | "avoidEscape": true 56 | } 57 | ], 58 | "@stylistic/comma-dangle": [ 59 | "error", 60 | "always-multiline" 61 | ], 62 | "@stylistic/comma-spacing": [ 63 | "error", 64 | { 65 | "before": false, 66 | "after": true 67 | } 68 | ], 69 | "@stylistic/no-multi-spaces": [ 70 | "error", 71 | { 72 | "ignoreEOLComments": false 73 | } 74 | ], 75 | "@stylistic/array-bracket-spacing": [ 76 | "error", 77 | "never" 78 | ], 79 | "@stylistic/array-bracket-newline": [ 80 | "error", 81 | "consistent" 82 | ], 83 | "@stylistic/object-curly-spacing": [ 84 | "error", 85 | "always" 86 | ], 87 | "@stylistic/object-curly-newline": [ 88 | "error", 89 | { 90 | "multiline": true, 91 | "consistent": true 92 | } 93 | ], 94 | "@stylistic/object-property-newline": [ 95 | "error", 96 | { 97 | "allowAllPropertiesOnSameLine": true 98 | } 99 | ], 100 | "@stylistic/keyword-spacing": [ 101 | "error" 102 | ], 103 | "@stylistic/brace-style": [ 104 | "error", 105 | "1tbs", 106 | { 107 | "allowSingleLine": true 108 | } 109 | ], 110 | "@stylistic/space-before-blocks": [ 111 | "error" 112 | ], 113 | "@stylistic/member-delimiter-style": [ 114 | "error" 115 | ], 116 | "@stylistic/semi": [ 117 | "error", 118 | "always" 119 | ], 120 | "@stylistic/max-len": [ 121 | "error", 122 | { 123 | "code": 150, 124 | "ignoreUrls": true, 125 | "ignoreStrings": true, 126 | "ignoreTemplateLiterals": true, 127 | "ignoreComments": true, 128 | "ignoreRegExpLiterals": true 129 | } 130 | ], 131 | "@stylistic/quote-props": [ 132 | "error", 133 | "consistent-as-needed" 134 | ], 135 | "@stylistic/key-spacing": [ 136 | "error" 137 | ], 138 | "@stylistic/no-multiple-empty-lines": [ 139 | "error" 140 | ], 141 | "@stylistic/no-trailing-spaces": [ 142 | "error" 143 | ], 144 | "curly": [ 145 | "error", 146 | "multi-line", 147 | "consistent" 148 | ], 149 | "@typescript-eslint/no-require-imports": "error", 150 | "import/no-extraneous-dependencies": [ 151 | "error", 152 | { 153 | "devDependencies": [ 154 | "**/test/**", 155 | "**/build-tools/**", 156 | ".projenrc.ts", 157 | "projenrc/**/*.ts" 158 | ], 159 | "optionalDependencies": false, 160 | "peerDependencies": true 161 | } 162 | ], 163 | "import/no-unresolved": [ 164 | "error" 165 | ], 166 | "import/order": [ 167 | "warn", 168 | { 169 | "groups": [ 170 | "builtin", 171 | "external" 172 | ], 173 | "alphabetize": { 174 | "order": "asc", 175 | "caseInsensitive": true 176 | } 177 | } 178 | ], 179 | "import/no-duplicates": [ 180 | "error" 181 | ], 182 | "no-shadow": [ 183 | "off" 184 | ], 185 | "@typescript-eslint/no-shadow": "error", 186 | "@typescript-eslint/no-floating-promises": "error", 187 | "no-return-await": [ 188 | "off" 189 | ], 190 | "@typescript-eslint/return-await": "error", 191 | "dot-notation": [ 192 | "error" 193 | ], 194 | "no-bitwise": [ 195 | "error" 196 | ], 197 | "@typescript-eslint/member-ordering": [ 198 | "error", 199 | { 200 | "default": [ 201 | "public-static-field", 202 | "public-static-method", 203 | "protected-static-field", 204 | "protected-static-method", 205 | "private-static-field", 206 | "private-static-method", 207 | "field", 208 | "constructor", 209 | "method" 210 | ] 211 | } 212 | ] 213 | }, 214 | "overrides": [ 215 | { 216 | "files": [ 217 | ".projenrc.ts" 218 | ], 219 | "rules": { 220 | "@typescript-eslint/no-require-imports": "off", 221 | "import/no-extraneous-dependencies": "off" 222 | } 223 | } 224 | ] 225 | } 226 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | * text=auto eol=lf 4 | *.snap linguist-generated 5 | /.eslintrc.json linguist-generated 6 | /.gitattributes linguist-generated 7 | /.github/pull_request_template.md linguist-generated 8 | /.github/workflows/auto-approve.yml linguist-generated 9 | /.github/workflows/build.yml linguist-generated 10 | /.github/workflows/pull-request-lint.yml linguist-generated 11 | /.github/workflows/release.yml linguist-generated 12 | /.github/workflows/upgrade-main.yml linguist-generated 13 | /.gitignore linguist-generated 14 | /.mergify.yml linguist-generated 15 | /.npmignore linguist-generated 16 | /.projen/** linguist-generated 17 | /.projen/deps.json linguist-generated 18 | /.projen/files.json linguist-generated 19 | /.projen/tasks.json linguist-generated 20 | /API.md linguist-generated 21 | /LICENSE linguist-generated 22 | /package.json linguist-generated 23 | /tsconfig.dev.json linguist-generated 24 | /yarn.lock linguist-generated -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Fixes # -------------------------------------------------------------------------------- /.github/workflows/auto-approve.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: auto-approve 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | jobs: 13 | approve: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | pull-requests: write 17 | if: contains(github.event.pull_request.labels.*.name, 'auto-approve') && (github.event.pull_request.user.login == 'cdklabs-automation') 18 | steps: 19 | - uses: hmarr/auto-approve-action@v2.2.1 20 | with: 21 | github-token: ${{ secrets.GITHUB_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: build 4 | on: 5 | pull_request: {} 6 | workflow_dispatch: {} 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: write 12 | outputs: 13 | self_mutation_happened: ${{ steps.self_mutation.outputs.self_mutation_happened }} 14 | env: 15 | CI: "true" 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | with: 20 | ref: ${{ github.event.pull_request.head.ref }} 21 | repository: ${{ github.event.pull_request.head.repo.full_name }} 22 | - name: Setup Node.js 23 | uses: actions/setup-node@v4 24 | with: 25 | node-version: lts/* 26 | - name: Install dependencies 27 | run: yarn install --check-files 28 | - name: build 29 | run: npx projen build 30 | - name: Find mutations 31 | id: self_mutation 32 | run: |- 33 | git add . 34 | git diff --staged --patch --exit-code > repo.patch || echo "self_mutation_happened=true" >> $GITHUB_OUTPUT 35 | working-directory: ./ 36 | - name: Upload patch 37 | if: steps.self_mutation.outputs.self_mutation_happened 38 | uses: actions/upload-artifact@v4.4.0 39 | with: 40 | name: repo.patch 41 | path: repo.patch 42 | overwrite: true 43 | - name: Fail build on mutation 44 | if: steps.self_mutation.outputs.self_mutation_happened 45 | run: |- 46 | echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch." 47 | cat repo.patch 48 | exit 1 49 | - name: Backup artifact permissions 50 | run: cd dist && getfacl -R . > permissions-backup.acl 51 | continue-on-error: true 52 | - name: Upload artifact 53 | uses: actions/upload-artifact@v4.4.0 54 | with: 55 | name: build-artifact 56 | path: dist 57 | overwrite: true 58 | self-mutation: 59 | needs: build 60 | runs-on: ubuntu-latest 61 | permissions: 62 | contents: write 63 | if: always() && needs.build.outputs.self_mutation_happened && !(github.event.pull_request.head.repo.full_name != github.repository) 64 | steps: 65 | - name: Checkout 66 | uses: actions/checkout@v4 67 | with: 68 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 69 | ref: ${{ github.event.pull_request.head.ref }} 70 | repository: ${{ github.event.pull_request.head.repo.full_name }} 71 | - name: Download patch 72 | uses: actions/download-artifact@v4 73 | with: 74 | name: repo.patch 75 | path: ${{ runner.temp }} 76 | - name: Apply patch 77 | run: '[ -s ${{ runner.temp }}/repo.patch ] && git apply ${{ runner.temp }}/repo.patch || echo "Empty patch. Skipping."' 78 | - name: Set git identity 79 | run: |- 80 | git config user.name "github-actions" 81 | git config user.email "github-actions@github.com" 82 | - name: Push changes 83 | env: 84 | PULL_REQUEST_REF: ${{ github.event.pull_request.head.ref }} 85 | run: |- 86 | git add . 87 | git commit -s -m "chore: self mutation" 88 | git push origin HEAD:$PULL_REQUEST_REF 89 | package-js: 90 | needs: build 91 | runs-on: ubuntu-latest 92 | permissions: 93 | contents: read 94 | if: ${{ !needs.build.outputs.self_mutation_happened }} 95 | steps: 96 | - uses: actions/setup-node@v4 97 | with: 98 | node-version: lts/* 99 | - name: Download build artifacts 100 | uses: actions/download-artifact@v4 101 | with: 102 | name: build-artifact 103 | path: dist 104 | - name: Restore build artifact permissions 105 | run: cd dist && setfacl --restore=permissions-backup.acl 106 | continue-on-error: true 107 | - name: Checkout 108 | uses: actions/checkout@v4 109 | with: 110 | ref: ${{ github.event.pull_request.head.ref }} 111 | repository: ${{ github.event.pull_request.head.repo.full_name }} 112 | path: .repo 113 | - name: Install Dependencies 114 | run: cd .repo && yarn install --check-files --frozen-lockfile 115 | - name: Extract build artifact 116 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 117 | - name: Move build artifact out of the way 118 | run: mv dist dist.old 119 | - name: Create js artifact 120 | run: cd .repo && npx projen package:js 121 | - name: Collect js artifact 122 | run: mv .repo/dist dist 123 | package-java: 124 | needs: build 125 | runs-on: ubuntu-latest 126 | permissions: 127 | contents: read 128 | if: ${{ !needs.build.outputs.self_mutation_happened }} 129 | steps: 130 | - uses: actions/setup-java@v4 131 | with: 132 | distribution: corretto 133 | java-version: "11" 134 | - uses: actions/setup-node@v4 135 | with: 136 | node-version: lts/* 137 | - name: Download build artifacts 138 | uses: actions/download-artifact@v4 139 | with: 140 | name: build-artifact 141 | path: dist 142 | - name: Restore build artifact permissions 143 | run: cd dist && setfacl --restore=permissions-backup.acl 144 | continue-on-error: true 145 | - name: Checkout 146 | uses: actions/checkout@v4 147 | with: 148 | ref: ${{ github.event.pull_request.head.ref }} 149 | repository: ${{ github.event.pull_request.head.repo.full_name }} 150 | path: .repo 151 | - name: Install Dependencies 152 | run: cd .repo && yarn install --check-files --frozen-lockfile 153 | - name: Extract build artifact 154 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 155 | - name: Move build artifact out of the way 156 | run: mv dist dist.old 157 | - name: Create java artifact 158 | run: cd .repo && npx projen package:java 159 | - name: Collect java artifact 160 | run: mv .repo/dist dist 161 | package-python: 162 | needs: build 163 | runs-on: ubuntu-latest 164 | permissions: 165 | contents: read 166 | if: ${{ !needs.build.outputs.self_mutation_happened }} 167 | steps: 168 | - uses: actions/setup-node@v4 169 | with: 170 | node-version: lts/* 171 | - uses: actions/setup-python@v5 172 | with: 173 | python-version: 3.x 174 | - name: Download build artifacts 175 | uses: actions/download-artifact@v4 176 | with: 177 | name: build-artifact 178 | path: dist 179 | - name: Restore build artifact permissions 180 | run: cd dist && setfacl --restore=permissions-backup.acl 181 | continue-on-error: true 182 | - name: Checkout 183 | uses: actions/checkout@v4 184 | with: 185 | ref: ${{ github.event.pull_request.head.ref }} 186 | repository: ${{ github.event.pull_request.head.repo.full_name }} 187 | path: .repo 188 | - name: Install Dependencies 189 | run: cd .repo && yarn install --check-files --frozen-lockfile 190 | - name: Extract build artifact 191 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 192 | - name: Move build artifact out of the way 193 | run: mv dist dist.old 194 | - name: Create python artifact 195 | run: cd .repo && npx projen package:python 196 | - name: Collect python artifact 197 | run: mv .repo/dist dist 198 | package-dotnet: 199 | needs: build 200 | runs-on: ubuntu-latest 201 | permissions: 202 | contents: read 203 | if: ${{ !needs.build.outputs.self_mutation_happened }} 204 | steps: 205 | - uses: actions/setup-node@v4 206 | with: 207 | node-version: lts/* 208 | - uses: actions/setup-dotnet@v4 209 | with: 210 | dotnet-version: 6.x 211 | - name: Download build artifacts 212 | uses: actions/download-artifact@v4 213 | with: 214 | name: build-artifact 215 | path: dist 216 | - name: Restore build artifact permissions 217 | run: cd dist && setfacl --restore=permissions-backup.acl 218 | continue-on-error: true 219 | - name: Checkout 220 | uses: actions/checkout@v4 221 | with: 222 | ref: ${{ github.event.pull_request.head.ref }} 223 | repository: ${{ github.event.pull_request.head.repo.full_name }} 224 | path: .repo 225 | - name: Install Dependencies 226 | run: cd .repo && yarn install --check-files --frozen-lockfile 227 | - name: Extract build artifact 228 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 229 | - name: Move build artifact out of the way 230 | run: mv dist dist.old 231 | - name: Create dotnet artifact 232 | run: cd .repo && npx projen package:dotnet 233 | - name: Collect dotnet artifact 234 | run: mv .repo/dist dist 235 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-lint.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: pull-request-lint 4 | on: 5 | pull_request_target: 6 | types: 7 | - labeled 8 | - opened 9 | - synchronize 10 | - reopened 11 | - ready_for_review 12 | - edited 13 | merge_group: {} 14 | jobs: 15 | validate: 16 | name: Validate PR title 17 | runs-on: ubuntu-latest 18 | permissions: 19 | pull-requests: write 20 | if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') 21 | steps: 22 | - uses: amannn/action-semantic-pull-request@v5.4.0 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | types: |- 27 | feat 28 | fix 29 | chore 30 | requireScope: false 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: release 4 | on: 5 | push: 6 | branches: 7 | - main 8 | workflow_dispatch: {} 9 | concurrency: 10 | group: ${{ github.workflow }} 11 | cancel-in-progress: false 12 | jobs: 13 | release: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: write 17 | outputs: 18 | latest_commit: ${{ steps.git_remote.outputs.latest_commit }} 19 | tag_exists: ${{ steps.check_tag_exists.outputs.exists }} 20 | env: 21 | CI: "true" 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | - name: Set git identity 28 | run: |- 29 | git config user.name "github-actions" 30 | git config user.email "github-actions@github.com" 31 | - name: Setup Node.js 32 | uses: actions/setup-node@v4 33 | with: 34 | node-version: lts/* 35 | - name: Install dependencies 36 | run: yarn install --check-files --frozen-lockfile 37 | - name: release 38 | run: npx projen release 39 | - name: Check if version has already been tagged 40 | id: check_tag_exists 41 | run: |- 42 | TAG=$(cat dist/releasetag.txt) 43 | ([ ! -z "$TAG" ] && git ls-remote -q --exit-code --tags origin $TAG && (echo "exists=true" >> $GITHUB_OUTPUT)) || (echo "exists=false" >> $GITHUB_OUTPUT) 44 | cat $GITHUB_OUTPUT 45 | - name: Check for new commits 46 | id: git_remote 47 | run: |- 48 | echo "latest_commit=$(git ls-remote origin -h ${{ github.ref }} | cut -f1)" >> $GITHUB_OUTPUT 49 | cat $GITHUB_OUTPUT 50 | - name: Backup artifact permissions 51 | if: ${{ steps.git_remote.outputs.latest_commit == github.sha }} 52 | run: cd dist && getfacl -R . > permissions-backup.acl 53 | continue-on-error: true 54 | - name: Upload artifact 55 | if: ${{ steps.git_remote.outputs.latest_commit == github.sha }} 56 | uses: actions/upload-artifact@v4.4.0 57 | with: 58 | name: build-artifact 59 | path: dist 60 | overwrite: true 61 | release_github: 62 | name: Publish to GitHub Releases 63 | needs: 64 | - release 65 | - release_npm 66 | - release_maven 67 | - release_pypi 68 | - release_nuget 69 | runs-on: ubuntu-latest 70 | permissions: 71 | contents: write 72 | if: needs.release.outputs.tag_exists != 'true' && needs.release.outputs.latest_commit == github.sha 73 | steps: 74 | - uses: actions/setup-node@v4 75 | with: 76 | node-version: lts/* 77 | - name: Download build artifacts 78 | uses: actions/download-artifact@v4 79 | with: 80 | name: build-artifact 81 | path: dist 82 | - name: Restore build artifact permissions 83 | run: cd dist && setfacl --restore=permissions-backup.acl 84 | continue-on-error: true 85 | - name: Release 86 | env: 87 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 88 | run: errout=$(mktemp); gh release create $(cat dist/releasetag.txt) -R $GITHUB_REPOSITORY -F dist/changelog.md -t $(cat dist/releasetag.txt) --target $GITHUB_SHA 2> $errout && true; exitcode=$?; if [ $exitcode -ne 0 ] && ! grep -q "Release.tag_name already exists" $errout; then cat $errout; exit $exitcode; fi 89 | release_npm: 90 | name: Publish to npm 91 | needs: release 92 | runs-on: ubuntu-latest 93 | permissions: 94 | id-token: write 95 | contents: read 96 | if: needs.release.outputs.tag_exists != 'true' && needs.release.outputs.latest_commit == github.sha 97 | steps: 98 | - uses: actions/setup-node@v4 99 | with: 100 | node-version: lts/* 101 | - name: Download build artifacts 102 | uses: actions/download-artifact@v4 103 | with: 104 | name: build-artifact 105 | path: dist 106 | - name: Restore build artifact permissions 107 | run: cd dist && setfacl --restore=permissions-backup.acl 108 | continue-on-error: true 109 | - name: Checkout 110 | uses: actions/checkout@v4 111 | with: 112 | path: .repo 113 | - name: Install Dependencies 114 | run: cd .repo && yarn install --check-files --frozen-lockfile 115 | - name: Extract build artifact 116 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 117 | - name: Move build artifact out of the way 118 | run: mv dist dist.old 119 | - name: Create js artifact 120 | run: cd .repo && npx projen package:js 121 | - name: Collect js artifact 122 | run: mv .repo/dist dist 123 | - name: Release 124 | env: 125 | NPM_DIST_TAG: latest 126 | NPM_REGISTRY: registry.npmjs.org 127 | NPM_CONFIG_PROVENANCE: "true" 128 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 129 | run: npx -p publib@latest publib-npm 130 | release_maven: 131 | name: Publish to Maven Central 132 | needs: release 133 | runs-on: ubuntu-latest 134 | permissions: 135 | contents: read 136 | if: needs.release.outputs.tag_exists != 'true' && needs.release.outputs.latest_commit == github.sha 137 | steps: 138 | - uses: actions/setup-java@v4 139 | with: 140 | distribution: corretto 141 | java-version: "11" 142 | - uses: actions/setup-node@v4 143 | with: 144 | node-version: lts/* 145 | - name: Download build artifacts 146 | uses: actions/download-artifact@v4 147 | with: 148 | name: build-artifact 149 | path: dist 150 | - name: Restore build artifact permissions 151 | run: cd dist && setfacl --restore=permissions-backup.acl 152 | continue-on-error: true 153 | - name: Checkout 154 | uses: actions/checkout@v4 155 | with: 156 | path: .repo 157 | - name: Install Dependencies 158 | run: cd .repo && yarn install --check-files --frozen-lockfile 159 | - name: Extract build artifact 160 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 161 | - name: Move build artifact out of the way 162 | run: mv dist dist.old 163 | - name: Create java artifact 164 | run: cd .repo && npx projen package:java 165 | - name: Collect java artifact 166 | run: mv .repo/dist dist 167 | - name: Release 168 | env: 169 | MAVEN_SERVER_ID: central-ossrh 170 | MAVEN_GPG_PRIVATE_KEY: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 171 | MAVEN_GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.MAVEN_GPG_PRIVATE_KEY_PASSPHRASE }} 172 | MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} 173 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} 174 | MAVEN_STAGING_PROFILE_ID: ${{ secrets.MAVEN_STAGING_PROFILE_ID }} 175 | run: npx -p publib@latest publib-maven 176 | release_pypi: 177 | name: Publish to PyPI 178 | needs: release 179 | runs-on: ubuntu-latest 180 | permissions: 181 | contents: read 182 | if: needs.release.outputs.tag_exists != 'true' && needs.release.outputs.latest_commit == github.sha 183 | steps: 184 | - uses: actions/setup-node@v4 185 | with: 186 | node-version: lts/* 187 | - uses: actions/setup-python@v5 188 | with: 189 | python-version: 3.x 190 | - name: Download build artifacts 191 | uses: actions/download-artifact@v4 192 | with: 193 | name: build-artifact 194 | path: dist 195 | - name: Restore build artifact permissions 196 | run: cd dist && setfacl --restore=permissions-backup.acl 197 | continue-on-error: true 198 | - name: Checkout 199 | uses: actions/checkout@v4 200 | with: 201 | path: .repo 202 | - name: Install Dependencies 203 | run: cd .repo && yarn install --check-files --frozen-lockfile 204 | - name: Extract build artifact 205 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 206 | - name: Move build artifact out of the way 207 | run: mv dist dist.old 208 | - name: Create python artifact 209 | run: cd .repo && npx projen package:python 210 | - name: Collect python artifact 211 | run: mv .repo/dist dist 212 | - name: Release 213 | env: 214 | TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} 215 | TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} 216 | run: npx -p publib@latest publib-pypi 217 | release_nuget: 218 | name: Publish to NuGet Gallery 219 | needs: release 220 | runs-on: ubuntu-latest 221 | permissions: 222 | contents: read 223 | if: needs.release.outputs.tag_exists != 'true' && needs.release.outputs.latest_commit == github.sha 224 | steps: 225 | - uses: actions/setup-node@v4 226 | with: 227 | node-version: lts/* 228 | - uses: actions/setup-dotnet@v4 229 | with: 230 | dotnet-version: 6.x 231 | - name: Download build artifacts 232 | uses: actions/download-artifact@v4 233 | with: 234 | name: build-artifact 235 | path: dist 236 | - name: Restore build artifact permissions 237 | run: cd dist && setfacl --restore=permissions-backup.acl 238 | continue-on-error: true 239 | - name: Checkout 240 | uses: actions/checkout@v4 241 | with: 242 | path: .repo 243 | - name: Install Dependencies 244 | run: cd .repo && yarn install --check-files --frozen-lockfile 245 | - name: Extract build artifact 246 | run: tar --strip-components=1 -xzvf dist/js/*.tgz -C .repo 247 | - name: Move build artifact out of the way 248 | run: mv dist dist.old 249 | - name: Create dotnet artifact 250 | run: cd .repo && npx projen package:dotnet 251 | - name: Collect dotnet artifact 252 | run: mv .repo/dist dist 253 | - name: Release 254 | env: 255 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} 256 | run: npx -p publib@latest publib-nuget 257 | -------------------------------------------------------------------------------- /.github/workflows/upgrade-main.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | name: upgrade-main 4 | on: 5 | workflow_dispatch: {} 6 | schedule: 7 | - cron: 0 0 * * * 8 | jobs: 9 | upgrade: 10 | name: Upgrade 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | outputs: 15 | patch_created: ${{ steps.create_patch.outputs.patch_created }} 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | with: 20 | ref: main 21 | - name: Setup Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: lts/* 25 | - name: Install dependencies 26 | run: yarn install --check-files --frozen-lockfile 27 | - name: Upgrade dependencies 28 | run: npx projen upgrade 29 | - name: Find mutations 30 | id: create_patch 31 | run: |- 32 | git add . 33 | git diff --staged --patch --exit-code > repo.patch || echo "patch_created=true" >> $GITHUB_OUTPUT 34 | working-directory: ./ 35 | - name: Upload patch 36 | if: steps.create_patch.outputs.patch_created 37 | uses: actions/upload-artifact@v4.4.0 38 | with: 39 | name: repo.patch 40 | path: repo.patch 41 | overwrite: true 42 | pr: 43 | name: Create Pull Request 44 | needs: upgrade 45 | runs-on: ubuntu-latest 46 | permissions: 47 | contents: read 48 | if: ${{ needs.upgrade.outputs.patch_created }} 49 | steps: 50 | - name: Checkout 51 | uses: actions/checkout@v4 52 | with: 53 | ref: main 54 | - name: Download patch 55 | uses: actions/download-artifact@v4 56 | with: 57 | name: repo.patch 58 | path: ${{ runner.temp }} 59 | - name: Apply patch 60 | run: '[ -s ${{ runner.temp }}/repo.patch ] && git apply ${{ runner.temp }}/repo.patch || echo "Empty patch. Skipping."' 61 | - name: Set git identity 62 | run: |- 63 | git config user.name "github-actions" 64 | git config user.email "github-actions@github.com" 65 | - name: Create Pull Request 66 | id: create-pr 67 | uses: peter-evans/create-pull-request@v6 68 | with: 69 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }} 70 | commit-message: |- 71 | chore(deps): upgrade dependencies 72 | 73 | Upgrades project dependencies. See details in [workflow run]. 74 | 75 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 76 | 77 | ------ 78 | 79 | *Automatically created by projen via the "upgrade-main" workflow* 80 | branch: github-actions/upgrade-main 81 | title: "chore(deps): upgrade dependencies" 82 | labels: auto-approve 83 | body: |- 84 | Upgrades project dependencies. See details in [workflow run]. 85 | 86 | [Workflow Run]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 87 | 88 | ------ 89 | 90 | *Automatically created by projen via the "upgrade-main" workflow* 91 | author: github-actions 92 | committer: github-actions 93 | signoff: true 94 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | !/.gitattributes 3 | !/.projen/tasks.json 4 | !/.projen/deps.json 5 | !/.projen/files.json 6 | !/.github/workflows/pull-request-lint.yml 7 | !/.github/workflows/auto-approve.yml 8 | !/package.json 9 | !/LICENSE 10 | !/.npmignore 11 | logs 12 | *.log 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | lerna-debug.log* 17 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | lib-cov 23 | coverage 24 | *.lcov 25 | .nyc_output 26 | build/Release 27 | node_modules/ 28 | jspm_packages/ 29 | *.tsbuildinfo 30 | .eslintcache 31 | *.tgz 32 | .yarn-integrity 33 | .cache 34 | /test-reports/ 35 | junit.xml 36 | /coverage/ 37 | !/.github/workflows/build.yml 38 | /dist/changelog.md 39 | /dist/version.txt 40 | !/.github/workflows/release.yml 41 | !/.mergify.yml 42 | !/.github/workflows/upgrade-main.yml 43 | !/.github/pull_request_template.md 44 | !/test/ 45 | !/tsconfig.dev.json 46 | !/src/ 47 | /lib 48 | /dist/ 49 | !/.eslintrc.json 50 | .jsii 51 | tsconfig.json 52 | !/API.md 53 | !/.projenrc.ts 54 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | 3 | queue_rules: 4 | - name: default 5 | update_method: merge 6 | conditions: 7 | - "#approved-reviews-by>=1" 8 | - -label~=(do-not-merge) 9 | - status-success=build 10 | - status-success=package-js 11 | - status-success=package-java 12 | - status-success=package-python 13 | - status-success=package-dotnet 14 | merge_method: squash 15 | commit_message_template: |- 16 | {{ title }} (#{{ number }}) 17 | 18 | {{ body }} 19 | pull_request_rules: 20 | - name: Automatic merge on approval and successful build 21 | actions: 22 | delete_head_branch: {} 23 | queue: 24 | name: default 25 | conditions: 26 | - "#approved-reviews-by>=1" 27 | - -label~=(do-not-merge) 28 | - status-success=build 29 | - status-success=package-js 30 | - status-success=package-java 31 | - status-success=package-python 32 | - status-success=package-dotnet 33 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | *.md 3 | .gitattributes 4 | /.projen/ 5 | /test-reports/ 6 | junit.xml 7 | /coverage/ 8 | permissions-backup.acl 9 | /dist/changelog.md 10 | /dist/version.txt 11 | /.mergify.yml 12 | /test/ 13 | /tsconfig.dev.json 14 | /src/ 15 | !/lib/ 16 | !/lib/**/*.js 17 | !/lib/**/*.d.ts 18 | dist 19 | /tsconfig.json 20 | /.github/ 21 | /.vscode/ 22 | /.idea/ 23 | /.projenrc.js 24 | tsconfig.tsbuildinfo 25 | /.eslintrc.json 26 | !.jsii 27 | /.gitattributes 28 | /.projenrc.ts 29 | /projenrc 30 | -------------------------------------------------------------------------------- /.projen/deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "@stylistic/eslint-plugin", 5 | "version": "^2", 6 | "type": "build" 7 | }, 8 | { 9 | "name": "@types/jest", 10 | "type": "build" 11 | }, 12 | { 13 | "name": "@types/node", 14 | "type": "build" 15 | }, 16 | { 17 | "name": "@typescript-eslint/eslint-plugin", 18 | "version": "^8", 19 | "type": "build" 20 | }, 21 | { 22 | "name": "@typescript-eslint/parser", 23 | "version": "^8", 24 | "type": "build" 25 | }, 26 | { 27 | "name": "cdk-nag", 28 | "type": "build" 29 | }, 30 | { 31 | "name": "commit-and-tag-version", 32 | "version": "^12", 33 | "type": "build" 34 | }, 35 | { 36 | "name": "eslint-import-resolver-typescript", 37 | "type": "build" 38 | }, 39 | { 40 | "name": "eslint-plugin-import", 41 | "type": "build" 42 | }, 43 | { 44 | "name": "eslint", 45 | "version": "^9", 46 | "type": "build" 47 | }, 48 | { 49 | "name": "jest", 50 | "type": "build" 51 | }, 52 | { 53 | "name": "jest-junit", 54 | "version": "^16", 55 | "type": "build" 56 | }, 57 | { 58 | "name": "jsii-diff", 59 | "type": "build" 60 | }, 61 | { 62 | "name": "jsii-docgen", 63 | "version": "^10.5.0", 64 | "type": "build" 65 | }, 66 | { 67 | "name": "jsii-pacmak", 68 | "type": "build" 69 | }, 70 | { 71 | "name": "jsii-rosetta", 72 | "version": "~5.6.0", 73 | "type": "build" 74 | }, 75 | { 76 | "name": "jsii", 77 | "version": "~5.6.0", 78 | "type": "build" 79 | }, 80 | { 81 | "name": "projen", 82 | "type": "build" 83 | }, 84 | { 85 | "name": "ts-jest", 86 | "type": "build" 87 | }, 88 | { 89 | "name": "ts-node", 90 | "type": "build" 91 | }, 92 | { 93 | "name": "typescript", 94 | "type": "build" 95 | }, 96 | { 97 | "name": "aws-cdk-lib", 98 | "version": "^2.24.1", 99 | "type": "peer" 100 | }, 101 | { 102 | "name": "constructs", 103 | "version": "^10.0.5", 104 | "type": "peer" 105 | } 106 | ], 107 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 108 | } 109 | -------------------------------------------------------------------------------- /.projen/files.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | ".eslintrc.json", 4 | ".gitattributes", 5 | ".github/pull_request_template.md", 6 | ".github/workflows/auto-approve.yml", 7 | ".github/workflows/build.yml", 8 | ".github/workflows/pull-request-lint.yml", 9 | ".github/workflows/release.yml", 10 | ".github/workflows/upgrade-main.yml", 11 | ".gitignore", 12 | ".mergify.yml", 13 | ".projen/deps.json", 14 | ".projen/files.json", 15 | ".projen/tasks.json", 16 | "LICENSE", 17 | "tsconfig.dev.json" 18 | ], 19 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 20 | } 21 | -------------------------------------------------------------------------------- /.projen/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasks": { 3 | "build": { 4 | "name": "build", 5 | "description": "Full release build", 6 | "steps": [ 7 | { 8 | "spawn": "default" 9 | }, 10 | { 11 | "spawn": "pre-compile" 12 | }, 13 | { 14 | "spawn": "compile" 15 | }, 16 | { 17 | "spawn": "post-compile" 18 | }, 19 | { 20 | "spawn": "test" 21 | }, 22 | { 23 | "spawn": "package" 24 | } 25 | ] 26 | }, 27 | "bump": { 28 | "name": "bump", 29 | "description": "Bumps version based on latest git tag and generates a changelog entry", 30 | "env": { 31 | "OUTFILE": "package.json", 32 | "CHANGELOG": "dist/changelog.md", 33 | "BUMPFILE": "dist/version.txt", 34 | "RELEASETAG": "dist/releasetag.txt", 35 | "RELEASE_TAG_PREFIX": "", 36 | "BUMP_PACKAGE": "commit-and-tag-version@^12" 37 | }, 38 | "steps": [ 39 | { 40 | "builtin": "release/bump-version" 41 | } 42 | ], 43 | "condition": "git log --oneline -1 | grep -qv \"chore(release):\"" 44 | }, 45 | "clobber": { 46 | "name": "clobber", 47 | "description": "hard resets to HEAD of origin and cleans the local repo", 48 | "env": { 49 | "BRANCH": "$(git branch --show-current)" 50 | }, 51 | "steps": [ 52 | { 53 | "exec": "git checkout -b scratch", 54 | "name": "save current HEAD in \"scratch\" branch" 55 | }, 56 | { 57 | "exec": "git checkout $BRANCH" 58 | }, 59 | { 60 | "exec": "git fetch origin", 61 | "name": "fetch latest changes from origin" 62 | }, 63 | { 64 | "exec": "git reset --hard origin/$BRANCH", 65 | "name": "hard reset to origin commit" 66 | }, 67 | { 68 | "exec": "git clean -fdx", 69 | "name": "clean all untracked files" 70 | }, 71 | { 72 | "say": "ready to rock! (unpushed commits are under the \"scratch\" branch)" 73 | } 74 | ], 75 | "condition": "git diff --exit-code > /dev/null" 76 | }, 77 | "compat": { 78 | "name": "compat", 79 | "description": "Perform API compatibility check against latest version", 80 | "steps": [ 81 | { 82 | "exec": "jsii-diff npm:$(node -p \"require('./package.json').name\") -k --ignore-file .compatignore || (echo \"\nUNEXPECTED BREAKING CHANGES: add keys such as 'removed:constructs.Node.of' to .compatignore to skip.\n\" && exit 1)" 83 | } 84 | ] 85 | }, 86 | "compile": { 87 | "name": "compile", 88 | "description": "Only compile", 89 | "steps": [ 90 | { 91 | "exec": "jsii --silence-warnings=reserved-word" 92 | } 93 | ] 94 | }, 95 | "default": { 96 | "name": "default", 97 | "description": "Synthesize project files", 98 | "steps": [ 99 | { 100 | "exec": "ts-node --project tsconfig.dev.json .projenrc.ts" 101 | } 102 | ] 103 | }, 104 | "docgen": { 105 | "name": "docgen", 106 | "description": "Generate API.md from .jsii manifest", 107 | "steps": [ 108 | { 109 | "exec": "jsii-docgen -o API.md" 110 | } 111 | ] 112 | }, 113 | "eject": { 114 | "name": "eject", 115 | "description": "Remove projen from the project", 116 | "env": { 117 | "PROJEN_EJECTING": "true" 118 | }, 119 | "steps": [ 120 | { 121 | "spawn": "default" 122 | } 123 | ] 124 | }, 125 | "eslint": { 126 | "name": "eslint", 127 | "description": "Runs eslint against the codebase", 128 | "env": { 129 | "ESLINT_USE_FLAT_CONFIG": "false" 130 | }, 131 | "steps": [ 132 | { 133 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern $@ src test build-tools projenrc .projenrc.ts", 134 | "receiveArgs": true 135 | } 136 | ] 137 | }, 138 | "install": { 139 | "name": "install", 140 | "description": "Install project dependencies and update lockfile (non-frozen)", 141 | "steps": [ 142 | { 143 | "exec": "yarn install --check-files" 144 | } 145 | ] 146 | }, 147 | "install:ci": { 148 | "name": "install:ci", 149 | "description": "Install project dependencies using frozen lockfile", 150 | "steps": [ 151 | { 152 | "exec": "yarn install --check-files --frozen-lockfile" 153 | } 154 | ] 155 | }, 156 | "package": { 157 | "name": "package", 158 | "description": "Creates the distribution package", 159 | "steps": [ 160 | { 161 | "spawn": "package:js", 162 | "condition": "node -e \"if (!process.env.CI) process.exit(1)\"" 163 | }, 164 | { 165 | "spawn": "package-all", 166 | "condition": "node -e \"if (process.env.CI) process.exit(1)\"" 167 | } 168 | ] 169 | }, 170 | "package-all": { 171 | "name": "package-all", 172 | "description": "Packages artifacts for all target languages", 173 | "steps": [ 174 | { 175 | "spawn": "package:js" 176 | }, 177 | { 178 | "spawn": "package:java" 179 | }, 180 | { 181 | "spawn": "package:python" 182 | }, 183 | { 184 | "spawn": "package:dotnet" 185 | } 186 | ] 187 | }, 188 | "package:dotnet": { 189 | "name": "package:dotnet", 190 | "description": "Create dotnet language bindings", 191 | "steps": [ 192 | { 193 | "exec": "jsii-pacmak -v --target dotnet" 194 | } 195 | ] 196 | }, 197 | "package:java": { 198 | "name": "package:java", 199 | "description": "Create java language bindings", 200 | "steps": [ 201 | { 202 | "exec": "jsii-pacmak -v --target java" 203 | } 204 | ] 205 | }, 206 | "package:js": { 207 | "name": "package:js", 208 | "description": "Create js language bindings", 209 | "steps": [ 210 | { 211 | "exec": "jsii-pacmak -v --target js" 212 | } 213 | ] 214 | }, 215 | "package:python": { 216 | "name": "package:python", 217 | "description": "Create python language bindings", 218 | "steps": [ 219 | { 220 | "exec": "jsii-pacmak -v --target python" 221 | } 222 | ] 223 | }, 224 | "post-compile": { 225 | "name": "post-compile", 226 | "description": "Runs after successful compilation", 227 | "steps": [ 228 | { 229 | "spawn": "docgen" 230 | } 231 | ] 232 | }, 233 | "post-upgrade": { 234 | "name": "post-upgrade", 235 | "description": "Runs after upgrading dependencies" 236 | }, 237 | "pre-compile": { 238 | "name": "pre-compile", 239 | "description": "Prepare the project for compilation" 240 | }, 241 | "release": { 242 | "name": "release", 243 | "description": "Prepare a release from \"main\" branch", 244 | "env": { 245 | "RELEASE": "true" 246 | }, 247 | "steps": [ 248 | { 249 | "exec": "rm -fr dist" 250 | }, 251 | { 252 | "spawn": "bump" 253 | }, 254 | { 255 | "spawn": "build" 256 | }, 257 | { 258 | "spawn": "unbump" 259 | }, 260 | { 261 | "exec": "git diff --ignore-space-at-eol --exit-code" 262 | } 263 | ] 264 | }, 265 | "test": { 266 | "name": "test", 267 | "description": "Run tests", 268 | "steps": [ 269 | { 270 | "exec": "jest --passWithNoTests --updateSnapshot", 271 | "receiveArgs": true 272 | }, 273 | { 274 | "spawn": "eslint" 275 | } 276 | ] 277 | }, 278 | "test:watch": { 279 | "name": "test:watch", 280 | "description": "Run jest in watch mode", 281 | "steps": [ 282 | { 283 | "exec": "jest --watch" 284 | } 285 | ] 286 | }, 287 | "unbump": { 288 | "name": "unbump", 289 | "description": "Restores version to 0.0.0", 290 | "env": { 291 | "OUTFILE": "package.json", 292 | "CHANGELOG": "dist/changelog.md", 293 | "BUMPFILE": "dist/version.txt", 294 | "RELEASETAG": "dist/releasetag.txt", 295 | "RELEASE_TAG_PREFIX": "", 296 | "BUMP_PACKAGE": "commit-and-tag-version@^12" 297 | }, 298 | "steps": [ 299 | { 300 | "builtin": "release/reset-version" 301 | } 302 | ] 303 | }, 304 | "upgrade": { 305 | "name": "upgrade", 306 | "description": "upgrade dependencies", 307 | "env": { 308 | "CI": "0" 309 | }, 310 | "steps": [ 311 | { 312 | "exec": "npx npm-check-updates@16 --upgrade --target=minor --peer --no-deprecated --dep=dev,peer,prod,optional --filter=@types/jest,@types/node,cdk-nag,eslint-import-resolver-typescript,eslint-plugin-import,jest,jsii-diff,jsii-pacmak,projen,ts-jest,ts-node,typescript" 313 | }, 314 | { 315 | "exec": "yarn install --check-files" 316 | }, 317 | { 318 | "exec": "yarn upgrade @stylistic/eslint-plugin @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser cdk-nag commit-and-tag-version eslint-import-resolver-typescript eslint-plugin-import eslint jest jest-junit jsii-diff jsii-docgen jsii-pacmak jsii-rosetta jsii projen ts-jest ts-node typescript aws-cdk-lib constructs" 319 | }, 320 | { 321 | "exec": "npx projen" 322 | }, 323 | { 324 | "spawn": "post-upgrade" 325 | } 326 | ] 327 | }, 328 | "watch": { 329 | "name": "watch", 330 | "description": "Watch & compile in the background", 331 | "steps": [ 332 | { 333 | "exec": "jsii -w --silence-warnings=reserved-word" 334 | } 335 | ] 336 | } 337 | }, 338 | "env": { 339 | "PATH": "$(npx -c \"node --print process.env.PATH\")" 340 | }, 341 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 342 | } 343 | -------------------------------------------------------------------------------- /.projenrc.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { awscdk, javascript } from 'projen'; 5 | 6 | const project = new awscdk.AwsCdkConstructLibrary({ 7 | name: '@cdklabs/cdk-ethereum-node', 8 | projenrcTs: true, 9 | author: 'Amazon Web Services', 10 | authorAddress: 'https://aws.amazon.com', 11 | description: 'CDK construct to deploy an Ethereum node running on Amazon Managed Blockchain', 12 | license: 'MIT-0', 13 | copyrightOwner: 'Amazon.com, Inc. or its affiliates. All Rights Reserved.', 14 | defaultReleaseBranch: 'main', 15 | repositoryUrl: 'https://github.com/cdklabs/cdk-ethereum-node.git', 16 | cdkVersion: '2.24.1', 17 | autoApproveUpgrades: true, 18 | autoApproveOptions: { 19 | allowedUsernames: ['cdklabs-automation'], 20 | secret: 'GITHUB_TOKEN', 21 | }, 22 | peerDeps: [ 23 | 'constructs', 24 | 'aws-cdk-lib', 25 | ], 26 | devDeps: [ 27 | 'cdk-nag', 28 | ], 29 | npmignore: [ 30 | '*.md', 31 | '.gitattributes', 32 | '.jsii', 33 | ], 34 | npmAccess: javascript.NpmAccess.PUBLIC, 35 | publishToPypi: { 36 | distName: 'cdklabs.cdk-ethereum-node', 37 | module: 'cdklabs.cdk_ethereum_node', 38 | }, 39 | publishToMaven: { 40 | javaPackage: 'io.github.cdklabs.cdkethereumnode', 41 | mavenServerId: 'central-ossrh', 42 | mavenArtifactId: 'cdk-ethereum-node', 43 | mavenGroupId: 'io.github.cdklabs', 44 | }, 45 | publishToNuget: { 46 | dotNetNamespace: 'Cdklabs.CdkEthereumNode', 47 | packageId: 'Cdklabs.CdkEthereumNode', 48 | }, 49 | keywords: [ 50 | 'aws', 51 | 'awscdk', 52 | 'blockchain', 53 | 'cdk', 54 | 'ethereum', 55 | 'managedblockchain', 56 | 'aws::managedblockchain', 57 | 'aws-managedblockchain', 58 | ], 59 | }); 60 | 61 | project.synth(); 62 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # API Reference 2 | 3 | ## Constructs 4 | 5 | ### EthereumNode 6 | 7 | #### Initializers 8 | 9 | ```typescript 10 | import { EthereumNode } from '@cdklabs/cdk-ethereum-node' 11 | 12 | new EthereumNode(scope: Construct, id: string, props?: EthereumNodeProps) 13 | ``` 14 | 15 | | **Name** | **Type** | **Description** | 16 | | --- | --- | --- | 17 | | scope | constructs.Construct | *No description.* | 18 | | id | string | *No description.* | 19 | | props | EthereumNodeProps | *No description.* | 20 | 21 | --- 22 | 23 | ##### `scope`Required 24 | 25 | - *Type:* constructs.Construct 26 | 27 | --- 28 | 29 | ##### `id`Required 30 | 31 | - *Type:* string 32 | 33 | --- 34 | 35 | ##### `props`Optional 36 | 37 | - *Type:* EthereumNodeProps 38 | 39 | --- 40 | 41 | #### Methods 42 | 43 | | **Name** | **Description** | 44 | | --- | --- | 45 | | toString | Returns a string representation of this construct. | 46 | 47 | --- 48 | 49 | ##### `toString` 50 | 51 | ```typescript 52 | public toString(): string 53 | ``` 54 | 55 | Returns a string representation of this construct. 56 | 57 | #### Static Functions 58 | 59 | | **Name** | **Description** | 60 | | --- | --- | 61 | | isConstruct | Checks if `x` is a construct. | 62 | 63 | --- 64 | 65 | ##### ~~`isConstruct`~~ 66 | 67 | ```typescript 68 | import { EthereumNode } from '@cdklabs/cdk-ethereum-node' 69 | 70 | EthereumNode.isConstruct(x: any) 71 | ``` 72 | 73 | Checks if `x` is a construct. 74 | 75 | ###### `x`Required 76 | 77 | - *Type:* any 78 | 79 | Any object. 80 | 81 | --- 82 | 83 | #### Properties 84 | 85 | | **Name** | **Type** | **Description** | 86 | | --- | --- | --- | 87 | | node | constructs.Node | The tree node. | 88 | | availabilityZone | string | The Availability Zone in which the node exists. | 89 | | instanceType | InstanceType | The Amazon Managed Blockchain instance type for the node. | 90 | | network | Network | Managed Blockchain Ethereum network identifier. | 91 | | region | string | The Region in which the node exists. | 92 | 93 | --- 94 | 95 | ##### `node`Required 96 | 97 | ```typescript 98 | public readonly node: Node; 99 | ``` 100 | 101 | - *Type:* constructs.Node 102 | 103 | The tree node. 104 | 105 | --- 106 | 107 | ##### `availabilityZone`Required 108 | 109 | ```typescript 110 | public readonly availabilityZone: string; 111 | ``` 112 | 113 | - *Type:* string 114 | 115 | The Availability Zone in which the node exists. 116 | 117 | --- 118 | 119 | ##### `instanceType`Required 120 | 121 | ```typescript 122 | public readonly instanceType: InstanceType; 123 | ``` 124 | 125 | - *Type:* InstanceType 126 | 127 | The Amazon Managed Blockchain instance type for the node. 128 | 129 | --- 130 | 131 | ##### `network`Required 132 | 133 | ```typescript 134 | public readonly network: Network; 135 | ``` 136 | 137 | - *Type:* Network 138 | 139 | Managed Blockchain Ethereum network identifier. 140 | 141 | --- 142 | 143 | ##### `region`Required 144 | 145 | ```typescript 146 | public readonly region: string; 147 | ``` 148 | 149 | - *Type:* string 150 | 151 | The Region in which the node exists. 152 | 153 | --- 154 | 155 | 156 | ## Structs 157 | 158 | ### EthereumNodeProps 159 | 160 | Construct properties for `EthereumNode`. 161 | 162 | #### Initializer 163 | 164 | ```typescript 165 | import { EthereumNodeProps } from '@cdklabs/cdk-ethereum-node' 166 | 167 | const ethereumNodeProps: EthereumNodeProps = { ... } 168 | ``` 169 | 170 | #### Properties 171 | 172 | | **Name** | **Type** | **Description** | 173 | | --- | --- | --- | 174 | | availabilityZone | string | The Availability Zone in which the node will be created. | 175 | | instanceType | InstanceType | The Amazon Managed Blockchain instance type for the Ethereum node. | 176 | | network | Network | The Ethereum Network in which the node will be created. | 177 | 178 | --- 179 | 180 | ##### `availabilityZone`Optional 181 | 182 | ```typescript 183 | public readonly availabilityZone: string; 184 | ``` 185 | 186 | - *Type:* string 187 | - *Default:* us-east-1a 188 | 189 | The Availability Zone in which the node will be created. 190 | 191 | --- 192 | 193 | ##### `instanceType`Optional 194 | 195 | ```typescript 196 | public readonly instanceType: InstanceType; 197 | ``` 198 | 199 | - *Type:* InstanceType 200 | - *Default:* BURSTABLE3_LARGE 201 | 202 | The Amazon Managed Blockchain instance type for the Ethereum node. 203 | 204 | --- 205 | 206 | ##### `network`Optional 207 | 208 | ```typescript 209 | public readonly network: Network; 210 | ``` 211 | 212 | - *Type:* Network 213 | - *Default:* The default network selected is Mainnet network 214 | 215 | The Ethereum Network in which the node will be created. 216 | 217 | --- 218 | 219 | 220 | 221 | ## Enums 222 | 223 | ### InstanceType 224 | 225 | Supported instance types for Managed Blockchain nodes. 226 | 227 | #### Members 228 | 229 | | **Name** | **Description** | 230 | | --- | --- | 231 | | BURSTABLE3_XLARGE | *No description.* | 232 | | STANDARD5_XLARGE | *No description.* | 233 | | STANDARD5_XLARGE2 | *No description.* | 234 | | STANDARD5_XLARGE4 | *No description.* | 235 | | COMPUTE5_XLARGE2 | *No description.* | 236 | | COMPUTE5_XLARGE4 | *No description.* | 237 | 238 | --- 239 | 240 | ##### `BURSTABLE3_XLARGE` 241 | 242 | --- 243 | 244 | 245 | ##### `STANDARD5_XLARGE` 246 | 247 | --- 248 | 249 | 250 | ##### `STANDARD5_XLARGE2` 251 | 252 | --- 253 | 254 | 255 | ##### `STANDARD5_XLARGE4` 256 | 257 | --- 258 | 259 | 260 | ##### `COMPUTE5_XLARGE2` 261 | 262 | --- 263 | 264 | 265 | ##### `COMPUTE5_XLARGE4` 266 | 267 | --- 268 | 269 | 270 | ### Network 271 | 272 | Supported Ethereum networks for Managed Blockchain nodes. 273 | 274 | #### Members 275 | 276 | | **Name** | **Description** | 277 | | --- | --- | 278 | | MAINNET | *No description.* | 279 | | GOERLI | *No description.* | 280 | | RINKEBY | *No description.* | 281 | | ROPSTEN | *No description.* | 282 | 283 | --- 284 | 285 | ##### `MAINNET` 286 | 287 | --- 288 | 289 | 290 | ##### `GOERLI` 291 | 292 | --- 293 | 294 | 295 | ##### `RINKEBY` 296 | 297 | --- 298 | 299 | 300 | ##### `ROPSTEN` 301 | 302 | --- 303 | 304 | -------------------------------------------------------------------------------- /API.md.md: -------------------------------------------------------------------------------- 1 | # API Reference 2 | 3 | ## Constructs 4 | 5 | ### EthereumNode 6 | 7 | #### Initializers 8 | 9 | ```typescript 10 | import { EthereumNode } from '@cdklabs/cdk-ethereum-node' 11 | 12 | new EthereumNode(scope: Construct, id: string, props?: EthereumNodeProps) 13 | ``` 14 | 15 | | **Name** | **Type** | **Description** | 16 | | --- | --- | --- | 17 | | scope | constructs.Construct | *No description.* | 18 | | id | string | *No description.* | 19 | | props | EthereumNodeProps | *No description.* | 20 | 21 | --- 22 | 23 | ##### `scope`Required 24 | 25 | - *Type:* constructs.Construct 26 | 27 | --- 28 | 29 | ##### `id`Required 30 | 31 | - *Type:* string 32 | 33 | --- 34 | 35 | ##### `props`Optional 36 | 37 | - *Type:* EthereumNodeProps 38 | 39 | --- 40 | 41 | #### Methods 42 | 43 | | **Name** | **Description** | 44 | | --- | --- | 45 | | toString | Returns a string representation of this construct. | 46 | 47 | --- 48 | 49 | ##### `toString` 50 | 51 | ```typescript 52 | public toString(): string 53 | ``` 54 | 55 | Returns a string representation of this construct. 56 | 57 | #### Static Functions 58 | 59 | | **Name** | **Description** | 60 | | --- | --- | 61 | | isConstruct | Checks if `x` is a construct. | 62 | 63 | --- 64 | 65 | ##### ~~`isConstruct`~~ 66 | 67 | ```typescript 68 | import { EthereumNode } from '@cdklabs/cdk-ethereum-node' 69 | 70 | EthereumNode.isConstruct(x: any) 71 | ``` 72 | 73 | Checks if `x` is a construct. 74 | 75 | ###### `x`Required 76 | 77 | - *Type:* any 78 | 79 | Any object. 80 | 81 | --- 82 | 83 | #### Properties 84 | 85 | | **Name** | **Type** | **Description** | 86 | | --- | --- | --- | 87 | | node | constructs.Node | The tree node. | 88 | | availabilityZone | string | The Availability Zone in which the node exists. | 89 | | instanceType | InstanceType | The Amazon Managed Blockchain instance type for the node. | 90 | | network | Network | Managed Blockchain Ethereum network identifier. | 91 | | region | string | The Region in which the node exists. | 92 | 93 | --- 94 | 95 | ##### `node`Required 96 | 97 | ```typescript 98 | public readonly node: Node; 99 | ``` 100 | 101 | - *Type:* constructs.Node 102 | 103 | The tree node. 104 | 105 | --- 106 | 107 | ##### `availabilityZone`Required 108 | 109 | ```typescript 110 | public readonly availabilityZone: string; 111 | ``` 112 | 113 | - *Type:* string 114 | 115 | The Availability Zone in which the node exists. 116 | 117 | --- 118 | 119 | ##### `instanceType`Required 120 | 121 | ```typescript 122 | public readonly instanceType: InstanceType; 123 | ``` 124 | 125 | - *Type:* InstanceType 126 | 127 | The Amazon Managed Blockchain instance type for the node. 128 | 129 | --- 130 | 131 | ##### `network`Required 132 | 133 | ```typescript 134 | public readonly network: Network; 135 | ``` 136 | 137 | - *Type:* Network 138 | 139 | Managed Blockchain Ethereum network identifier. 140 | 141 | --- 142 | 143 | ##### `region`Required 144 | 145 | ```typescript 146 | public readonly region: string; 147 | ``` 148 | 149 | - *Type:* string 150 | 151 | The Region in which the node exists. 152 | 153 | --- 154 | 155 | 156 | ## Structs 157 | 158 | ### EthereumNodeProps 159 | 160 | Construct properties for `EthereumNode`. 161 | 162 | #### Initializer 163 | 164 | ```typescript 165 | import { EthereumNodeProps } from '@cdklabs/cdk-ethereum-node' 166 | 167 | const ethereumNodeProps: EthereumNodeProps = { ... } 168 | ``` 169 | 170 | #### Properties 171 | 172 | | **Name** | **Type** | **Description** | 173 | | --- | --- | --- | 174 | | availabilityZone | string | The Availability Zone in which the node will be created. | 175 | | instanceType | InstanceType | The Amazon Managed Blockchain instance type for the Ethereum node. | 176 | | network | Network | The Ethereum Network in which the node will be created. | 177 | 178 | --- 179 | 180 | ##### `availabilityZone`Optional 181 | 182 | ```typescript 183 | public readonly availabilityZone: string; 184 | ``` 185 | 186 | - *Type:* string 187 | - *Default:* us-east-1a 188 | 189 | The Availability Zone in which the node will be created. 190 | 191 | --- 192 | 193 | ##### `instanceType`Optional 194 | 195 | ```typescript 196 | public readonly instanceType: InstanceType; 197 | ``` 198 | 199 | - *Type:* InstanceType 200 | - *Default:* BURSTABLE3_LARGE 201 | 202 | The Amazon Managed Blockchain instance type for the Ethereum node. 203 | 204 | --- 205 | 206 | ##### `network`Optional 207 | 208 | ```typescript 209 | public readonly network: Network; 210 | ``` 211 | 212 | - *Type:* Network 213 | - *Default:* The default network selected is Mainnet network 214 | 215 | The Ethereum Network in which the node will be created. 216 | 217 | --- 218 | 219 | 220 | 221 | ## Enums 222 | 223 | ### InstanceType 224 | 225 | Supported instance types for Managed Blockchain nodes. 226 | 227 | #### Members 228 | 229 | | **Name** | **Description** | 230 | | --- | --- | 231 | | BURSTABLE3_LARGE | *No description.* | 232 | | BURSTABLE3_XLARGE | *No description.* | 233 | | STANDARD5_LARGE | *No description.* | 234 | | STANDARD5_XLARGE | *No description.* | 235 | | STANDARD5_XLARGE2 | *No description.* | 236 | | STANDARD5_XLARGE4 | *No description.* | 237 | | COMPUTE5_XLARGE | *No description.* | 238 | | COMPUTE5_XLARGE2 | *No description.* | 239 | | COMPUTE5_XLARGE4 | *No description.* | 240 | 241 | --- 242 | 243 | ##### `BURSTABLE3_LARGE` 244 | 245 | --- 246 | 247 | 248 | ##### `BURSTABLE3_XLARGE` 249 | 250 | --- 251 | 252 | 253 | ##### `STANDARD5_LARGE` 254 | 255 | --- 256 | 257 | 258 | ##### `STANDARD5_XLARGE` 259 | 260 | --- 261 | 262 | 263 | ##### `STANDARD5_XLARGE2` 264 | 265 | --- 266 | 267 | 268 | ##### `STANDARD5_XLARGE4` 269 | 270 | --- 271 | 272 | 273 | ##### `COMPUTE5_XLARGE` 274 | 275 | --- 276 | 277 | 278 | ##### `COMPUTE5_XLARGE2` 279 | 280 | --- 281 | 282 | 283 | ##### `COMPUTE5_XLARGE4` 284 | 285 | --- 286 | 287 | 288 | ### Network 289 | 290 | Supported Ethereum networks for Managed Blockchain nodes. 291 | 292 | #### Members 293 | 294 | | **Name** | **Description** | 295 | | --- | --- | 296 | | MAINNET | *No description.* | 297 | | GOERLI | *No description.* | 298 | | RINKEBY | *No description.* | 299 | | ROPSTEN | *No description.* | 300 | 301 | --- 302 | 303 | ##### `MAINNET` 304 | 305 | --- 306 | 307 | 308 | ##### `GOERLI` 309 | 310 | --- 311 | 312 | 313 | ##### `RINKEBY` 314 | 315 | --- 316 | 317 | 318 | ##### `ROPSTEN` 319 | 320 | --- 321 | 322 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ethereum on Amazon Managed Blockchain 2 | 3 | [![license](https://img.shields.io/github/license/cdklabs/cdk-ethereum-node?color=green)](https://opensource.org/licenses/MIT) 4 | [![release](https://img.shields.io/github/v/release/cdklabs/cdk-ethereum-node?color=green)](https://github.com/cdklabs/cdk-ethereum-node/releases) 5 | [![npm:version](https://img.shields.io/npm/v/@cdklabs/cdk-ethereum-node?color=blue)](https://www.npmjs.com/package/@cdklabs/cdk-ethereum-node) 6 | [![PyPi:version](https://img.shields.io/pypi/v/cdklabs.cdk-ethereum-node?color=blue)](https://pypi.org/project/cdklabs.cdk-ethereum-node/) 7 | [![Maven:version](https://img.shields.io/maven-central/v/io.github.cdklabs/cdk-ethereum-node?color=blue&label=maven)](https://central.sonatype.dev/artifact/io.github.cdklabs/cdk-ethereum-node/0.0.61) 8 | [![NuGet:version](https://img.shields.io/nuget/v/Cdklabs.CdkEthereumNode?color=blue)](https://www.nuget.org/packages/Cdklabs.CdkEthereumNode) 9 | 10 | 11 | This repository contains a CDK construct to deploy an Ethereum node running 12 | on Amazon Managed Blockchain. The following networks are supported: 13 | 14 | * Mainnet (default) 15 | * Testnet: Goerli 16 | * Testnet: Rinkeby 17 | * Testnet: Ropsten 18 | 19 | 20 | 21 | ## Installation 22 | 23 | Note that this construct requires [AWS CDK v2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install). 24 | 25 | #### JavaScript 26 | 27 | ```bash 28 | npm install --save @cdklabs/cdk-ethereum-node 29 | ``` 30 | 31 | #### Python 32 | 33 | ```bash 34 | pip3 install cdklabs.cdk-ethereum-node 35 | ``` 36 | 37 | #### Java 38 | 39 | Add the following to `pom.xml`: 40 | 41 | ```xml 42 | 43 | io.github.cdklabs 44 | cdk-ethereum-node 45 | 46 | ``` 47 | 48 | #### .NET 49 | 50 | ```bash 51 | dotnet add package Cdklabs.CdkEthereumNode 52 | ``` 53 | 54 | 55 | ## Usage 56 | 57 | A minimally complete deployment is shown below. By default, 58 | a `bc.t3.large` node will be created on the Ethereum Mainnet. 59 | 60 | ```typescript 61 | import { Stack, StackProps } from 'aws-cdk-lib'; 62 | import { Construct } from 'constructs'; 63 | import { EthereumNode, Network, InstanceType } from '@cdklabs/cdk-ethereum-node'; 64 | 65 | export class MyStack extends Stack { 66 | constructor(scope: Construct, id: string, props?: StackProps) { 67 | super(scope, id, props); 68 | new EthereumNode(this, 'Example'); 69 | } 70 | } 71 | 72 | ``` 73 | 74 | The equivalent Python code is as follows: 75 | 76 | ```python 77 | from aws_cdk import Stack 78 | from cdklabs.cdk_ethereum_node import EthereumNode 79 | 80 | class MyStack(Stack): 81 | def __init__(self, scope, id, **kwargs): 82 | super().__init__(scope, id, **kwargs) 83 | EthereumNode(self, 'Example') 84 | ``` 85 | 86 | The following is a more complex instantiation illustrating some of the node configuration options available. 87 | 88 | ```typescript 89 | new EthereumNode(this, 'Example', { 90 | network: Network.ROPSTEN, 91 | availabilityZone: 'us-east-1b', 92 | instanceType: InstanceType.BURSTABLE3_LARGE, 93 | }); 94 | ``` 95 | 96 | See the [API Documentation](API.md) for details on all available input and output parameters. 97 | 98 | 99 | ## References 100 | 101 | * [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html) 102 | * [Amazon Managed Blockchain](https://aws.amazon.com/managed-blockchain/) 103 | * [Ethereum](https://ethereum.org/en/developers/docs/) 104 | 105 | 106 | ## Contributing 107 | 108 | Pull requests are welcomed. Please review the [Contributing Guidelines](CONTRIBUTING.md) 109 | and the [Code of Conduct](CODE_OF_CONDUCT.md). 110 | 111 | 112 | ## Security 113 | 114 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 115 | 116 | 117 | ## Authors 118 | 119 | * Trinity Key (trinikey@amazon.com) 120 | * Marc Gozali (gozalim@amazon.com) 121 | 122 | 123 | ## License 124 | 125 | This project is licensed under the MIT-0 License. See the [LICENSE](LICENSE) file for details. 126 | -------------------------------------------------------------------------------- /examples/python/ethereum.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | 5 | from aws_cdk import Stack 6 | from cdklabs.cdk_ethereum_node import EthereumNode 7 | 8 | 9 | class MyStack(Stack): 10 | def __init__(self, scope, id, **kwargs): 11 | super().__init__(scope, id, **kwargs) 12 | EthereumNode(self, 'Example') 13 | -------------------------------------------------------------------------------- /examples/typescript/ethereum.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Stack, StackProps } from 'aws-cdk-lib'; 5 | import { Construct } from 'constructs'; 6 | import { EthereumNode } from '@cdklabs/cdk-ethereum-node'; 7 | 8 | export class MyStack extends Stack { 9 | constructor(scope: Construct, id: string, props?: StackProps) { 10 | super(scope, id, props); 11 | new EthereumNode(this, 'Example'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@cdklabs/cdk-ethereum-node", 3 | "description": "CDK construct to deploy an Ethereum node running on Amazon Managed Blockchain", 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/cdklabs/cdk-ethereum-node.git" 7 | }, 8 | "scripts": { 9 | "build": "npx projen build", 10 | "bump": "npx projen bump", 11 | "clobber": "npx projen clobber", 12 | "compat": "npx projen compat", 13 | "compile": "npx projen compile", 14 | "default": "npx projen default", 15 | "docgen": "npx projen docgen", 16 | "eject": "npx projen eject", 17 | "eslint": "npx projen eslint", 18 | "package": "npx projen package", 19 | "package-all": "npx projen package-all", 20 | "package:dotnet": "npx projen package:dotnet", 21 | "package:java": "npx projen package:java", 22 | "package:js": "npx projen package:js", 23 | "package:python": "npx projen package:python", 24 | "post-compile": "npx projen post-compile", 25 | "post-upgrade": "npx projen post-upgrade", 26 | "pre-compile": "npx projen pre-compile", 27 | "release": "npx projen release", 28 | "test": "npx projen test", 29 | "test:watch": "npx projen test:watch", 30 | "unbump": "npx projen unbump", 31 | "upgrade": "npx projen upgrade", 32 | "watch": "npx projen watch", 33 | "projen": "npx projen" 34 | }, 35 | "author": { 36 | "name": "Amazon Web Services", 37 | "url": "https://aws.amazon.com", 38 | "organization": false 39 | }, 40 | "devDependencies": { 41 | "@stylistic/eslint-plugin": "^2", 42 | "@types/jest": "^27", 43 | "@types/node": "^16 <= 16.18.78", 44 | "@typescript-eslint/eslint-plugin": "^8", 45 | "@typescript-eslint/parser": "^8", 46 | "aws-cdk-lib": "2.24.1", 47 | "cdk-nag": "^2.36.14", 48 | "commit-and-tag-version": "^12", 49 | "constructs": "10.0.5", 50 | "eslint": "^9", 51 | "eslint-import-resolver-typescript": "^3.10.1", 52 | "eslint-plugin-import": "^2.31.0", 53 | "jest": "^27", 54 | "jest-junit": "^16", 55 | "jsii": "~5.6.0", 56 | "jsii-diff": "^1.112.0", 57 | "jsii-docgen": "^10.5.0", 58 | "jsii-pacmak": "^1.112.0", 59 | "jsii-rosetta": "~5.6.0", 60 | "projen": "^0.92.10", 61 | "ts-jest": "^27", 62 | "ts-node": "^10.9.2", 63 | "typescript": "^4.9.5" 64 | }, 65 | "peerDependencies": { 66 | "aws-cdk-lib": "^2.24.1", 67 | "constructs": "^10.0.5" 68 | }, 69 | "keywords": [ 70 | "aws", 71 | "aws-managedblockchain", 72 | "aws::managedblockchain", 73 | "awscdk", 74 | "blockchain", 75 | "cdk", 76 | "ethereum", 77 | "managedblockchain" 78 | ], 79 | "main": "lib/index.js", 80 | "license": "MIT-0", 81 | "publishConfig": { 82 | "access": "public" 83 | }, 84 | "version": "0.0.0", 85 | "jest": { 86 | "coverageProvider": "v8", 87 | "testMatch": [ 88 | "/@(src|test)/**/*(*.)@(spec|test).ts?(x)", 89 | "/@(src|test)/**/__tests__/**/*.ts?(x)", 90 | "/@(projenrc)/**/*(*.)@(spec|test).ts?(x)", 91 | "/@(projenrc)/**/__tests__/**/*.ts?(x)" 92 | ], 93 | "clearMocks": true, 94 | "collectCoverage": true, 95 | "coverageReporters": [ 96 | "json", 97 | "lcov", 98 | "clover", 99 | "cobertura", 100 | "text" 101 | ], 102 | "coverageDirectory": "coverage", 103 | "coveragePathIgnorePatterns": [ 104 | "/node_modules/" 105 | ], 106 | "testPathIgnorePatterns": [ 107 | "/node_modules/" 108 | ], 109 | "watchPathIgnorePatterns": [ 110 | "/node_modules/" 111 | ], 112 | "reporters": [ 113 | "default", 114 | [ 115 | "jest-junit", 116 | { 117 | "outputDirectory": "test-reports" 118 | } 119 | ] 120 | ], 121 | "preset": "ts-jest", 122 | "globals": { 123 | "ts-jest": { 124 | "tsconfig": "tsconfig.dev.json" 125 | } 126 | } 127 | }, 128 | "types": "lib/index.d.ts", 129 | "stability": "stable", 130 | "jsii": { 131 | "outdir": "dist", 132 | "targets": { 133 | "java": { 134 | "package": "io.github.cdklabs.cdkethereumnode", 135 | "maven": { 136 | "groupId": "io.github.cdklabs", 137 | "artifactId": "cdk-ethereum-node" 138 | } 139 | }, 140 | "python": { 141 | "distName": "cdklabs.cdk-ethereum-node", 142 | "module": "cdklabs.cdk_ethereum_node" 143 | }, 144 | "dotnet": { 145 | "namespace": "Cdklabs.CdkEthereumNode", 146 | "packageId": "Cdklabs.CdkEthereumNode" 147 | } 148 | }, 149 | "tsc": { 150 | "outDir": "lib", 151 | "rootDir": "src" 152 | } 153 | }, 154 | "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." 155 | } 156 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | export * from './node'; 5 | 6 | export { SUPPORTED_REGIONS, SUPPORTED_AVAILABILITY_ZONES } from './utilities'; -------------------------------------------------------------------------------- /src/node.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import * as cdk from 'aws-cdk-lib'; 5 | import * as managedblockchain from 'aws-cdk-lib/aws-managedblockchain'; 6 | import * as constructs from 'constructs'; 7 | 8 | import * as utilities from './utilities'; 9 | 10 | /** 11 | * Supported instance types for Managed Blockchain nodes 12 | */ 13 | export enum InstanceType { 14 | BURSTABLE3_XLARGE = 'bc.t3.xlarge', 15 | STANDARD5_XLARGE = 'bc.m5.xlarge', 16 | STANDARD5_XLARGE2 = 'bc.m5.2xlarge', 17 | STANDARD5_XLARGE4 = 'bc.m5.4xlarge', 18 | COMPUTE5_XLARGE2 = 'bc.c5.2xlarge', 19 | COMPUTE5_XLARGE4 = 'bc.c5.4xlarge', 20 | } 21 | 22 | /** 23 | * Supported Ethereum networks for Managed Blockchain nodes 24 | */ 25 | export enum Network { 26 | MAINNET = 'n-ethereum-mainnet', 27 | GOERLI = 'n-ethereum-goerli', 28 | RINKEBY = 'n-ethereum-rinkeby', 29 | ROPSTEN = 'n-ethereum-ropsten', 30 | } 31 | 32 | /** 33 | * Construct properties for `EthereumNode` 34 | */ 35 | export interface EthereumNodeProps { 36 | 37 | /** 38 | * The Ethereum Network in which the node will be created 39 | * @default - The default network selected is Mainnet network 40 | */ 41 | readonly network?: Network; 42 | 43 | /** 44 | * The Amazon Managed Blockchain instance type for the Ethereum node 45 | * @default - BURSTABLE3_LARGE 46 | */ 47 | readonly instanceType?: InstanceType; 48 | 49 | /** 50 | * The Availability Zone in which the node will be created 51 | * @default - us-east-1a 52 | */ 53 | readonly availabilityZone?: string; 54 | 55 | } 56 | 57 | 58 | export class EthereumNode extends constructs.Construct { 59 | 60 | /** 61 | * Managed Blockchain Ethereum network identifier 62 | */ 63 | readonly network: Network; 64 | 65 | /** 66 | * The Amazon Managed Blockchain instance type for the node 67 | */ 68 | readonly instanceType: InstanceType; 69 | 70 | /** 71 | * The Region in which the node exists 72 | */ 73 | readonly region: string; 74 | 75 | /** 76 | * The Availability Zone in which the node exists 77 | */ 78 | readonly availabilityZone: string; 79 | 80 | /** 81 | * Creates an Ethereum public network node on an Amazon Managed Blockchain network 82 | */ 83 | constructor(scope: constructs.Construct, id: string, props?: EthereumNodeProps) { 84 | 85 | super(scope, id); 86 | 87 | const region = cdk.Stack.of(this).region; 88 | const availabilityZones = cdk.Stack.of(this).availabilityZones; 89 | var regionInEnvironment = !cdk.Token.isUnresolved(region); 90 | 91 | /** 92 | * Builds out Ethereum node given a list of input property objects, 93 | * using defaults if values not provided; additionally checks to ensure node deployment 94 | * is supported given region and availability zone 95 | */ 96 | if (typeof props === 'undefined') props = {}; 97 | // If no node configurations are provided, create one; the empty object 98 | // will be populated with defaults when passed to the node constructor 99 | this.network = props.network ?? Network.MAINNET; 100 | this.instanceType = props.instanceType ?? InstanceType.BURSTABLE3_XLARGE; 101 | this.region = region; 102 | 103 | // If no availability zone is provided, use the first in the region. 104 | if (regionInEnvironment) { 105 | utilities.validateRegion(region); 106 | this.availabilityZone = props.availabilityZone ?? `${region}a`; 107 | utilities.validateAvailabilityZone(region, this.availabilityZone); 108 | } else { 109 | this.availabilityZone = props.availabilityZone ?? availabilityZones[0]; 110 | } 111 | 112 | /** 113 | * Build out CloudFormation resources populating with input values or defaults if none provided 114 | */ 115 | new managedblockchain.CfnNode(this, id, { 116 | networkId: this.network, 117 | nodeConfiguration: { 118 | availabilityZone: this.availabilityZone, 119 | instanceType: this.instanceType, 120 | }, 121 | }); 122 | 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/utilities.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | /** 5 | * Regions where Managed Blockchain is supported, for details see 6 | * https://aws.amazon.com/managed-blockchain/pricing/hyperledger/ 7 | */ 8 | export const SUPPORTED_REGIONS = [ 9 | 'ap-northeast-1', 10 | 'ap-northeast-2', 11 | 'ap-southeast-1', 12 | 'eu-west-1', 13 | 'eu-west-2', 14 | 'us-east-1', 15 | ]; 16 | 17 | /** 18 | * Map of supported regions to their availability zones 19 | */ 20 | export const SUPPORTED_AVAILABILITY_ZONES: Record> = { 21 | 'ap-northeast-1': [ 22 | 'ap-northeast-1a', 23 | 'ap-northeast-1b', 24 | 'ap-northeast-1c', 25 | ], 26 | 'ap-northeast-2': [ 27 | 'ap-northeast-2a', 28 | 'ap-northeast-2b', 29 | 'ap-northeast-2c', 30 | 'ap-northeast-2d', 31 | ], 32 | 'ap-southeast-1': [ 33 | 'ap-southeast-1a', 34 | 'ap-southeast-1b', 35 | 'ap-southeast-1c', 36 | ], 37 | 'eu-west-1': [ 38 | 'eu-west-1a', 39 | 'eu-west-1b', 40 | 'eu-west-1c', 41 | ], 42 | 'eu-west-2': [ 43 | 'eu-west-2a', 44 | 'eu-west-2b', 45 | 'eu-west-2c', 46 | ], 47 | 'us-east-1': [ 48 | 'us-east-1a', 49 | 'us-east-1b', 50 | 'us-east-1c', 51 | 'us-east-1d', 52 | 'us-east-1e', 53 | 'us-east-1f', 54 | ], 55 | }; 56 | 57 | /** 58 | * Throw an error if provided region is not in the supported list 59 | */ 60 | export function validateRegion(region: string) { 61 | if (!SUPPORTED_REGIONS.includes(region)) { 62 | const regionList = SUPPORTED_REGIONS.join(', '); 63 | throw new Error(`Managed Blockchain is only available in the following regions: ${regionList}.`); 64 | } 65 | } 66 | 67 | /** 68 | * Throw an error if provided availability zone is not in the supported list 69 | */ 70 | export function validateAvailabilityZone(region: string, availabilityZone?: string) { 71 | const availabililtyZonesForRegion = SUPPORTED_AVAILABILITY_ZONES[region]; 72 | if (typeof availabilityZone === 'undefined' || !availabililtyZonesForRegion.includes(availabilityZone)) { 73 | const availabilityZoneList = availabililtyZonesForRegion.join(', '); 74 | throw new Error(`Managed Blockchain in ${region} is only available in the following availability zones: ${availabilityZoneList}.`); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /test/node.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import * as cdk from 'aws-cdk-lib'; 5 | import * as assertions from 'aws-cdk-lib/assertions'; 6 | 7 | import * as ethereum from '../src'; 8 | 9 | const DEFAULT_ENV = { env: { region: 'us-east-1' } }; 10 | 11 | describe('EthereumNode', () => { 12 | 13 | test('Create an Ethereum node with the default configuration', () => { 14 | const app = new cdk.App(); 15 | const stack = new cdk.Stack(app, 'TestStack', DEFAULT_ENV); 16 | const node = new ethereum.EthereumNode(stack, 'TestEthereumPublicNetwork', {}); 17 | const template = assertions.Template.fromStack(stack); 18 | template.resourceCountIs('AWS::ManagedBlockchain::Node', 1); 19 | template.hasResource('AWS::ManagedBlockchain::Node', { 20 | Properties: { 21 | NodeConfiguration: { 22 | AvailabilityZone: 'us-east-1a', 23 | InstanceType: 'bc.t3.xlarge', 24 | }, 25 | }, 26 | }); 27 | expect(node.network).toBe(ethereum.Network.MAINNET); 28 | expect(node.availabilityZone).toBe('us-east-1a'); 29 | expect(node.instanceType).toBe(ethereum.InstanceType.BURSTABLE3_XLARGE); 30 | }); 31 | 32 | test('Create an Ethereum node with a custom configuration', () => { 33 | const app = new cdk.App(); 34 | const stack = new cdk.Stack(app, 'TestStack', DEFAULT_ENV); 35 | const node = new ethereum.EthereumNode(stack, 'TestEthereumPublicNetwork', { 36 | network: ethereum.Network.MAINNET, 37 | availabilityZone: 'us-east-1b', 38 | instanceType: ethereum.InstanceType.BURSTABLE3_XLARGE, 39 | }); 40 | const template = assertions.Template.fromStack(stack); 41 | template.resourceCountIs('AWS::ManagedBlockchain::Node', 1); 42 | template.hasResource('AWS::ManagedBlockchain::Node', { 43 | Properties: { 44 | NodeConfiguration: { 45 | AvailabilityZone: 'us-east-1b', 46 | InstanceType: 'bc.t3.xlarge', 47 | }, 48 | }, 49 | }); 50 | expect(node.network).toBe(ethereum.Network.MAINNET); 51 | expect(node.availabilityZone).toBe('us-east-1b'); 52 | expect(node.instanceType).toBe(ethereum.InstanceType.BURSTABLE3_XLARGE); 53 | }); 54 | 55 | test('Fail to create a node in an invalid availability zone', () => { 56 | expect(ethereum.SUPPORTED_AVAILABILITY_ZONES).not.toContain('us-west-1a'); 57 | const mismatchedAvailabilityZone = () => { 58 | const app = new cdk.App(); 59 | const stack = new cdk.Stack(app, 'TestStack', DEFAULT_ENV); 60 | new ethereum.EthereumNode(stack, 'TestEthereumNode', { availabilityZone: 'us-west-1a' }); 61 | }; 62 | expect(ethereum.SUPPORTED_AVAILABILITY_ZONES['us-east-1']).not.toContain('us-east-1z'); 63 | const nonexistantAvailabilityZone = () => { 64 | const app = new cdk.App(); 65 | const stack = new cdk.Stack(app, 'TestStack', DEFAULT_ENV); 66 | new ethereum.EthereumNode(stack, 'TestEthereumNode', { availabilityZone: 'us-east-1z' }); 67 | }; 68 | expect(mismatchedAvailabilityZone).toThrow(Error); 69 | expect(nonexistantAvailabilityZone).toThrow(Error); 70 | }); 71 | 72 | test('Fail to create a node in an unsupported region', () => { 73 | expect(ethereum.SUPPORTED_REGIONS).not.toContain('us-west-1'); 74 | const unsupportedRegion = () => { 75 | const app = new cdk.App(); 76 | const unsupported_region = { env: { region: 'us-west-1' } }; 77 | const stack = new cdk.Stack(app, 'TestStack', unsupported_region); 78 | new ethereum.EthereumNode(stack, 'TestEthereumNode'); 79 | }; 80 | expect(unsupportedRegion).toThrow(Error); 81 | }); 82 | 83 | }); 84 | -------------------------------------------------------------------------------- /tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". 2 | { 3 | "compilerOptions": { 4 | "alwaysStrict": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "inlineSourceMap": true, 9 | "inlineSources": true, 10 | "lib": [ 11 | "es2020" 12 | ], 13 | "module": "CommonJS", 14 | "noEmitOnError": false, 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "noImplicitThis": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "resolveJsonModule": true, 22 | "strict": true, 23 | "strictNullChecks": true, 24 | "strictPropertyInitialization": true, 25 | "stripInternal": true, 26 | "target": "ES2020" 27 | }, 28 | "include": [ 29 | "src/**/*.ts", 30 | "test/**/*.ts", 31 | ".projenrc.ts", 32 | "projenrc/**/*.ts" 33 | ], 34 | "exclude": [ 35 | "node_modules" 36 | ] 37 | } 38 | --------------------------------------------------------------------------------