├── .editorconfig ├── .eslintrc.js ├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ ├── build-test.yml │ ├── create-release-pr.yml │ ├── publish-release.yml │ └── require-additional-reviewer.yml ├── .gitignore ├── .nvmrc ├── .prettierrc.js ├── CHANGELOG.md ├── README.md ├── images └── icon.svg ├── index.html ├── package.json ├── scripts ├── build-website.js └── cleanup.sh ├── snap.config.js ├── snap.manifest.json ├── src └── index.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['@metamask/eslint-config'], 5 | 6 | overrides: [ 7 | { 8 | files: ['*.js'], 9 | parserOptions: { 10 | sourceType: 'script', 11 | }, 12 | globals: { 13 | wallet: 'readonly', 14 | }, 15 | extends: ['@metamask/eslint-config-nodejs'], 16 | }, 17 | 18 | { 19 | files: ['*.test.js'], 20 | extends: ['@metamask/eslint-config-jest'], 21 | }, 22 | ], 23 | 24 | ignorePatterns: ['!.eslintrc.js', '!.prettierrc.js', 'dist/'], 25 | }; 26 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | * @MetaMask/devs 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Please see the documentation for all configuration options: 2 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 3 | 4 | version: 2 5 | updates: 6 | - package-ecosystem: 'npm' 7 | directory: '/' 8 | schedule: 9 | interval: 'daily' 10 | time: '06:00' 11 | allow: 12 | - dependency-name: '@metamask/*' 13 | target-branch: 'main' 14 | versioning-strategy: 'increase-if-necessary' 15 | open-pull-requests-limit: 10 16 | -------------------------------------------------------------------------------- /.github/workflows/build-test.yml: -------------------------------------------------------------------------------- 1 | name: Build, Lint, and Test 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | 8 | jobs: 9 | build-lint-test: 10 | name: Build, Lint, and Test 11 | runs-on: ubuntu-20.04 12 | strategy: 13 | matrix: 14 | node-version: [16.x, 18.x] 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | - name: Get Yarn cache directory 22 | run: echo "::set-output name=YARN_CACHE_DIR::$(yarn cache dir)" 23 | id: yarn-cache-dir 24 | - name: Get Yarn version 25 | run: echo "::set-output name=YARN_VERSION::$(yarn --version)" 26 | id: yarn-version 27 | - name: Cache yarn dependencies 28 | uses: actions/cache@v2 29 | with: 30 | path: ${{ steps.yarn-cache-dir.outputs.YARN_CACHE_DIR }} 31 | key: yarn-cache-${{ runner.os }}-${{ steps.yarn-version.outputs.YARN_VERSION }}-${{ hashFiles('yarn.lock') }} 32 | - run: yarn --frozen-lockfile 33 | - run: yarn build 34 | - run: yarn lint 35 | - run: yarn test 36 | - name: Validate RC changelog 37 | if: ${{ startsWith(github.head_ref, 'release/') }} 38 | run: yarn auto-changelog validate --rc 39 | - name: Validate changelog 40 | if: ${{ !startsWith(github.head_ref, 'release/') }} 41 | run: yarn auto-changelog validate 42 | all-jobs-pass: 43 | name: All jobs pass 44 | runs-on: ubuntu-20.04 45 | needs: 46 | - build-lint-test 47 | steps: 48 | - run: echo "Great success!" 49 | -------------------------------------------------------------------------------- /.github/workflows/create-release-pr.yml: -------------------------------------------------------------------------------- 1 | name: Create Release Pull Request 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | base-branch: 7 | description: 'The base branch for git operations and the pull request.' 8 | default: 'main' 9 | required: true 10 | release-type: 11 | description: 'A SemVer version diff, i.e. major, minor, patch, prerelease etc. Mutually exclusive with "release-version".' 12 | required: false 13 | release-version: 14 | description: 'A specific version to bump to. Mutually exclusive with "release-type".' 15 | required: false 16 | 17 | jobs: 18 | create-release-pr: 19 | runs-on: ubuntu-latest 20 | permissions: 21 | contents: write 22 | pull-requests: write 23 | steps: 24 | - uses: actions/checkout@v2 25 | with: 26 | # This is to guarantee that the most recent tag is fetched. 27 | # This can be configured to a more reasonable value by consumers. 28 | fetch-depth: 0 29 | # We check out the specified branch, which will be used as the base 30 | # branch for all git operations and the release PR. 31 | ref: ${{ github.event.inputs.base-branch }} 32 | - name: Get Node.js version 33 | id: nvm 34 | run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) 35 | - uses: actions/setup-node@v2 36 | with: 37 | node-version: ${{ steps.nvm.outputs.NODE_VERSION }} 38 | - uses: MetaMask/action-create-release-pr@v1 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | with: 42 | release-type: ${{ github.event.inputs.release-type }} 43 | release-version: ${{ github.event.inputs.release-version }} 44 | artifacts-path: gh-action__release-authors 45 | # Upload the release author artifact for use in subsequent workflows 46 | - uses: actions/upload-artifact@v2 47 | with: 48 | name: release-authors 49 | path: gh-action__release-authors 50 | if-no-files-found: error 51 | -------------------------------------------------------------------------------- /.github/workflows/publish-release.yml: -------------------------------------------------------------------------------- 1 | name: Publish Release 2 | 3 | on: 4 | pull_request: 5 | types: [closed] 6 | 7 | jobs: 8 | publish-release: 9 | permissions: 10 | contents: write 11 | if: | 12 | github.event.pull_request.merged == true && 13 | startsWith(github.event.pull_request.head.ref, 'release/') 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | # We check out the release pull request's base branch, which will be 19 | # used as the base branch for all git operations. 20 | ref: ${{ github.event.pull_request.base.ref }} 21 | - name: Get Node.js version 22 | id: nvm 23 | run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) 24 | - uses: actions/setup-node@v2 25 | with: 26 | node-version: ${{ steps.nvm.outputs.NODE_VERSION }} 27 | - uses: MetaMask/action-publish-release@v1 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | - name: Get Yarn cache directory 31 | run: echo "::set-output name=YARN_CACHE_DIR::$(yarn cache dir)" 32 | id: yarn-cache-dir 33 | - name: Get Yarn version 34 | run: echo "::set-output name=YARN_VERSION::$(yarn --version)" 35 | id: yarn-version 36 | - name: Cache yarn dependencies 37 | uses: actions/cache@v2 38 | with: 39 | path: ${{ steps.yarn-cache-dir.outputs.YARN_CACHE_DIR }} 40 | key: yarn-cache-${{ runner.os }}-${{ steps.yarn-version.outputs.YARN_VERSION }}-${{ hashFiles('yarn.lock') }} 41 | - run: yarn --frozen-lockfile 42 | - run: yarn build 43 | - run: yarn build:website 44 | - name: Publish to GitHub Pages 45 | uses: MetaMask/action-publish-gh-pages@v2 46 | with: 47 | source-directory: public 48 | -------------------------------------------------------------------------------- /.github/workflows/require-additional-reviewer.yml: -------------------------------------------------------------------------------- 1 | name: Require Additional Reviewer for Releases 2 | 3 | on: 4 | pull_request: 5 | pull_request_review: 6 | 7 | jobs: 8 | require-additional-reviewer: 9 | permissions: 10 | actions: read 11 | contents: read 12 | pull-requests: read 13 | statuses: write 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | # If the base branch has been merged into the release branch, we 19 | # need to find the earliest common ancestor commit of the base and 20 | # release branches. 21 | fetch-depth: 0 22 | # We want the head / feature branch to be checked out, and we will 23 | # compare it to the base branch in the action. 24 | ref: ${{ github.event.pull_request.head.ref }} 25 | - uses: MetaMask/action-require-additional-reviewer@v1 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | with: 29 | read-org-token: ${{ secrets.ORG_READER }} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | dist/ 3 | coverage/ 4 | public/ 5 | 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (https://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directories 37 | node_modules/ 38 | 39 | # TypeScript cache 40 | *.tsbuildinfo 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Microbundle cache 49 | .rpt2_cache/ 50 | .rts2_cache_cjs/ 51 | .rts2_cache_es/ 52 | .rts2_cache_umd/ 53 | 54 | # Optional REPL history 55 | .node_repl_history 56 | 57 | # Output of 'npm pack' 58 | *.tgz 59 | 60 | # Yarn Integrity file 61 | .yarn-integrity 62 | 63 | # dotenv environment variables file 64 | .env 65 | .env.test 66 | 67 | # Stores VSCode versions used for testing VSCode extensions 68 | .vscode-test 69 | 70 | # yarn v2 71 | .yarn/cache 72 | .yarn/unplugged 73 | .yarn/build-state.yml 74 | .yarn/install-state.gz 75 | .pnp.* 76 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v16 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // All of these are defaults except singleQuote, but we specify them 2 | // for explicitness 3 | module.exports = { 4 | quoteProps: 'as-needed', 5 | singleQuote: true, 6 | tabWidth: 2, 7 | trailingComma: 'all', 8 | }; 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [0.7.0] 10 | ### Changed 11 | - Package renamed to `@metamask/template-snap` 12 | - @metamask/snaps-cli@0.7.0 ([#4](https://github.com/MetaMask/snap-template/pull/4)) 13 | - Add more content to the custom confirmation 14 | - Add cleanup script, more instructions in readme 15 | 16 | ## [0.6.1] 17 | ### Fixed 18 | - `snap_confirm` call ([#168](https://github.com/MetaMask/snaps-skunkworks/pull/168)) 19 | - The Snap was passing invalid parameters to the method. 20 | 21 | ## [0.6.0] 22 | ### Added 23 | - SVG icon ([#163](https://github.com/MetaMask/snaps-skunkworks/pull/163)) 24 | - Adds an icon file at `images/icon.svg` and a reference to it in `snap.manifest.json`. 25 | 26 | ### Changed 27 | - **BREAKING:** Support the new Snaps publishing specification ([#140](https://github.com/MetaMask/snaps-skunkworks/pull/140), [#157](https://github.com/MetaMask/snaps-skunkworks/pull/157)) 28 | - This introduces several breaking changes to how Snaps are developed, hosted, and represented at runtime. See [the specification](https://github.com/MetaMask/specifications/blob/d4a5bf5d6990bb5b02a98bd3f95a24ffb28c701c/snaps/publishing.md) and the referenced pull requests for details. 29 | 30 | ## [0.4.0] 31 | ### Added 32 | - Initial release. 33 | 34 | [Unreleased]: https://github.com/MetaMask/snap-template/compare/v0.7.0...HEAD 35 | [0.7.0]: https://github.com/MetaMask/snap-template/compare/v0.6.1...v0.7.0 36 | [0.6.1]: https://github.com/MetaMask/snap-template/compare/v0.6.0...v0.6.1 37 | [0.6.0]: https://github.com/MetaMask/snap-template/compare/v0.4.0...v0.6.0 38 | [0.4.0]: https://github.com/MetaMask/snap-template/releases/tag/v0.4.0 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ DEPRECATED 2 | 3 | This repository is no longer being supported. Please consider using [`@metamask/template-snap-monorepo`](https://github.com/MetaMask/template-snap-monorepo/). 4 | -------------------------------------------------------------------------------- /images/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello, Snaps! 5 | 6 | 7 | 8 | 9 |

Hello, Snaps!

10 |
11 | Instructions 12 | 24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 65 | 66 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@metamask/template-snap", 3 | "version": "0.7.0", 4 | "description": "The 'Hello, world!' of MetaMask Snaps.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/MetaMask/snap-template.git" 8 | }, 9 | "license": "MIT", 10 | "main": "src/index.js", 11 | "files": [ 12 | "dist/", 13 | "images/", 14 | "snap.manifest.json" 15 | ], 16 | "scripts": { 17 | "build:clean": "yarn clean && yarn build", 18 | "build:website": "node ./scripts/build-website.js", 19 | "build": "mm-snap build", 20 | "serve": "mm-snap serve", 21 | "watch": "mm-snap watch", 22 | "clean": "rimraf dist/*", 23 | "test": "echo 'TODO'", 24 | "lint:eslint": "eslint . --cache --ext js,ts", 25 | "lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' --ignore-path .gitignore", 26 | "lint": "yarn lint:eslint && yarn lint:misc --check", 27 | "lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write", 28 | "lint:changelog": "yarn auto-changelog validate" 29 | }, 30 | "devDependencies": { 31 | "@metamask/auto-changelog": "^3.0.0", 32 | "@metamask/eslint-config": "^8.0.0", 33 | "@metamask/eslint-config-jest": "^8.0.0", 34 | "@metamask/eslint-config-nodejs": "^8.0.0", 35 | "@metamask/snaps-cli": "^0.23.0", 36 | "eslint": "^7.30.0", 37 | "eslint-config-prettier": "^8.3.0", 38 | "eslint-plugin-import": "^2.23.4", 39 | "eslint-plugin-jest": "^24.4.0", 40 | "eslint-plugin-node": "^11.1.0", 41 | "eslint-plugin-prettier": "^3.4.0", 42 | "mkdirp": "^1.0.4", 43 | "prettier": "^2.3.2", 44 | "rimraf": "^3.0.2" 45 | }, 46 | "publishConfig": { 47 | "access": "public", 48 | "registry": "https://registry.npmjs.org/" 49 | }, 50 | "engines": { 51 | "node": ">=16.0.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /scripts/build-website.js: -------------------------------------------------------------------------------- 1 | const { promises: fs } = require('fs'); 2 | const path = require('path'); 3 | const mkdirp = require('mkdirp'); 4 | 5 | main(); 6 | 7 | async function main() { 8 | const rootPath = path.resolve(__dirname, '../'); 9 | const publicPath = path.join(rootPath, 'public/'); 10 | const imagesPath = path.join(publicPath, 'images/'); 11 | 12 | await mkdirp(imagesPath); 13 | await fs.copyFile( 14 | path.join(rootPath, 'images/icon.svg'), 15 | path.join(imagesPath, 'icon.svg'), 16 | ); 17 | 18 | const htmlContents = await fs.readFile( 19 | path.join(rootPath, 'index.html'), 20 | 'utf8', 21 | ); 22 | await fs.writeFile( 23 | path.join(publicPath, 'index.html'), 24 | htmlContents.replace( 25 | // eslint-disable-next-line no-template-curly-in-string 26 | 'const snapId = `local:${window.location.href}`;', 27 | 'const snapId = `npm:@metamask/template-snap`;', 28 | ), 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /scripts/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -u 4 | set -o pipefail 5 | 6 | rm .github/CODEOWNERS 7 | rm .github/workflows/require-additional-reviewer.yml 8 | rm -f scripts/cleanup.sh 9 | git commit -am "Clean up undesired MetaMask GitHub files" 10 | -------------------------------------------------------------------------------- /snap.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | cliOptions: { 3 | port: 8080, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /snap.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.7.0", 3 | "proposedName": "MetaMask Template Snap", 4 | "description": "A MetaMask Snap template.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/MetaMask/snap-template.git" 8 | }, 9 | "source": { 10 | "shasum": "W4FN/2A1mQSjjrO95MGptw7pr+UR8913AOIksoajQSo=", 11 | "location": { 12 | "npm": { 13 | "filePath": "dist/bundle.js", 14 | "iconPath": "images/icon.svg", 15 | "packageName": "@metamask/template-snap", 16 | "registry": "https://registry.npmjs.org/" 17 | } 18 | } 19 | }, 20 | "initialPermissions": { 21 | "snap_confirm": {} 22 | }, 23 | "manifestVersion": "0.1" 24 | } 25 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | module.exports.onRpcRequest = async ({ origin, request }) => { 2 | switch (request.method) { 3 | case 'hello': 4 | return wallet.request({ 5 | method: 'snap_confirm', 6 | params: [ 7 | { 8 | prompt: `Hello, ${origin}!`, 9 | description: 10 | 'This custom confirmation is just for display purposes.', 11 | textAreaContent: 12 | 'But you can edit the snap source code to make it do something, if you want to!', 13 | }, 14 | ], 15 | }); 16 | default: 17 | throw new Error('Method not found.'); 18 | } 19 | }; 20 | --------------------------------------------------------------------------------